有人可以解释一下,Delphi 7中MultiSelectStyleSelectedSelected.Count属性如何用于TTreeView吗?我离开Delphi编码已经有很多年了,除非有人指出我,否则我会错过什么,我认为这背后绝对没有逻辑。

要点。我有一个例程,用选定文件夹的内容填充TTreeView。它使用递归,因此每个文件夹都表示为带有子节点的节点-它是子文件夹和文件。由于MultiSelect设置为True,因此用户可以选择树上的多个项目。在MultiSelectStyle组中,我还将所有四个子属性都设置为True(也许是一个错误)。

作为我程序的调试(我希望它的工作恰好相反),我有以下代码:

ShowMessage(IntToStr(tvShell.Selected.Count) + ' selected');

for i := 0 to (tvShell.Selected.Count - 1) do
begin
    ShowMessage(tvShell.Selected.Item[i].Text);
end;


因此,我运行程序并选择任何文件夹。树渲染,我看到:


根节点,所选文件夹的完整路径为Text,并且具有六个子节点,因为所选文件夹包含六个子文件夹且没有文件,
这六个子文件夹仅包含文件,因此根节点的六个子文件夹包含数量可观的子文件夹,例如-第一个包含44个(文件或项目),最后一个包含9个(项目或文件)。


使用Ctrl和鼠标,我选择第一个(44个文件)和最后一个(9个文件)树节点(根节点的子节点),然后单击执行上述调试代码的按钮。



我期望什么?我看到选择了两个项目。由于msVisibleOnly中的True设置为MultiSelectStyle,因此我希望将tvShell.Selected.Count设置为2并看到三则消息。

我能得到什么?第一条消息说我有...选择了九个项目,当我继续时,我又得到了另外九个消息,向我显示了最后一个文件夹(树子)的内容。最有趣的是,在tvShell.Selected中没有这两个信号,实际上是我选择的! WTF?

废话继续...

我重复所有这些步骤,但是这次我选择(单击)最后一个文件夹(子级),并按下Ctrl按钮,然后单击第一个文件夹(root的子级)。作为人类,我再次看到,我选择了两个项目。看着这棵树,我在视觉上看不出选择的区别。但是德尔福确实如此。

当执行调试代码时,这次我得到的信息是选择了44个项目,并且还获得了44个附加的消息框,它们显示了第一个文件夹的内容。完全困惑,我要单击第一个和最后一个文件夹旁边的+以查看是否在其中选择了任何项目,但是没有(因为msVisibleOnly设置为True)。

我知道了,它是如何工作的(总是声称上次单击的项目的孩子都在选定的项目中),但是我不明白。这背后的逻辑在哪里?如果代码的结果不能反映现实情况,这将如何有用?

抱歉,我的舌头很硬,但这对我来说完全是愚蠢的。由于我不使用Delphi编写代码(我实际上讨厌这种语言来做更多类似的事情),所以我不需要寻求启发或解释,为什么这样做会起作用(尽管如果有人有空余时间,我会非常乐于阅读)。

但是,如果有人可以向我解释,我必须在代码中以及TTreeView属性中做什么魔术,才能从代码中获得真正选择的内容,而不是Delphi对现实的错误解释,我真的很高兴。如果我看到选择了两个项目,则我希望tvShell.Selected.Count设置为2,并且我希望tvShell.Selected恰好包含两个项目-两者都是我选择的。仅此而已。

抱歉,这个问题这么长,但是当我(多年以后)再次发现Delphi确实是一种奇怪的语言时,我不得不在遇到挫折之后做出反应。

最佳答案

您的代码显示了

tvShell.Selected.Count


这是tvShell.Selected的直接子级的节点数。请记住,tvShell.Selected仅仅是一个节点。

您可能打算使用

tvShell.SelectionCount


然后你显示

tvShell.Selected.Item[i].Text


这些是tvShell.Selected的直接子代的标题。

如果要遍历所有选定的节点,则可以这样进行:

for i := 0 to tvShell.SelectionCount-1 do
  DoSomething(tvShell.Selections[i]);




在遇到这种情况时,建议阅读联机帮助。特别是对于Delphi 7,文档非常清晰。对于Selected,文档说明:


在树视图中指定选定的节点。

选择的属性:TTreeNode;

描述

读取选定内容以访问树视图的选定节点。如果有
如果没有选定节点,则“选定”的值为nil。

.....

如果MultiSelect属性为True,而MultiSelectStyle属性为
包含msControlSelect,然后Selected返回最后单击的节点
启用,即使该单击取消选择了该节点。对于当前选择
如果MultiSelect为True,则请参见Selections属性。


然后,当您继续阅读Count的文档时,它会说:


指示树节点的直接后代数目。

属性计数:整数;

描述

使用计数确定有多少个子节点属于一个树节点。
伯爵只包括直系子女,不包括其后代。
遍历树的子级时,计数可能很有用
节点。


换句话说,文档告诉您的内容与我告诉您的相同。

07-28 03:27
查看更多