delphi - 了解 Delphi 7 中多选 TTreeView 项的工作原理

标签 delphi treeview delphi-7 multi-select

谁能解释一下,如何MultiSelectStyle , SelectedSelected.Count属性适用于 TTreeView在德尔福 7 中?我已经离开 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 的根节点并且有六个 child ,因为所选文件夹包含六个子文件夹且没有文件,
  • 这六个子文件夹仅包含文件,因此根节点的六个子节点包含相应数量的子节点,例如 - 第一个包含 44 个(文件或项目),最后一个包含 9 个(项目或文件)。

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

    Example tree contents

    我期待什么?我看到了已选择两项 .由于msVisibleOnly设置为 True其中MultiSelectStyle , 我希望有 tvShell.Selected.Count设置为 2并看到三个消息。

    我能得到什么?第一条消息说我有... 选择了九个项目当我继续时,我收到了另外九条消息,显示了最后一个文件夹(树子)的内容。最有趣的部分是tvShell.Selected那两个都没有,居然是我选的!怎么回事?

    胡说八道继续……

    我重复所有这些步骤,但这次我选择(单击)最后一个文件夹(子文件夹)并使用 Ctrl按下按钮,我点击第一个文件夹(根的 child )。作为人类,我再次看到,我拥有 已选择两项 .看这棵树时,我在视觉上看不出选择有什么不同。但德尔福做到了。

    执行调试代码时,这次我得到的信息是 已选择四十四项 我收到了 44 个额外的消息框,显示了第一个文件夹的内容。完全糊涂了,我点了+在第一个和最后一个文件夹旁边查看,如果里面有任何项目被选中,但没有(因为 msVisibleOnly 设置为 True )。

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

    对不起,舌头很硬,但这对我来说完全是愚蠢的。由于我不在 Delphi 中编码(我实际上讨厌这种语言来做更多类似的事情)我不寻求启发或解释,为什么这会像它一样有效(尽管,如果有人有空闲时间,我会非常乐意阅读它)。

    但我真的会很高兴,如果有人可以解释我,我必须在代码中和 TTreeView 中做些什么魔法属性,从代码中得到,什么才是真正的选择,而不是Delphi对现实的错误解释。如果我看到两个项目被选中,我想要 tvShell.Selected.Count设置为 2 我想要 tvShell.Selected正好包含两个项目——我选择的两个项目。不多也不少。

    抱歉,这个问题太长了,但是当我发现(再次,多年后)感到沮丧之后,我不得不使用react,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该文件指出:

    Specifies the selected node in the tree view.

    property Selected: TTreeNode;

    Description

    Read Selected to access the selected node of the tree view. If there is no selected node, the value of Selected is nil.

    .....

    If the MultiSelect property is True and the MultiSelectStyle property includes msControlSelect, then Selected returns the last node clicked on, even if that click deselected the node. For a current selection status when MultiSelect is True, refer to the Selections property.



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

    Indicates the number of direct descendants of a tree node.

    property Count: Integer;

    Description

    Use Count to determine how many child nodes belong to a tree node. Count includes only immediate children, and not their descendants. Count can be useful when iterating through the children of a tree node.



    换句话说,文档告诉你的和我告诉你的一样。

    关于delphi - 了解 Delphi 7 中多选 TTreeView 项的工作原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14215150/

    相关文章:

    android - 如何用Delphi XE5制作安卓动态壁纸?

    c# - 从 DataTable 填充 WinForms TreeView

    treeview - 如何使用 TornadoFX TreeView 显示数据

    delphi - 在Delphi中查找 "non-leak"内存使用问题的策略或工具?

    delphi - 如何获得 Firemonkey 中的默认系统颜色?

    multithreading - 将消息发布到之前未显示的框架后应用程序挂起

    delphi - 当用键盘打开弹出窗口时,如何使 Tpopupmenu 预选第一个菜单项

    c++ - MFC TreeView 控件 : looking for a foolproof way to deal with data

    delphi - 如何将 nil 传递给 var 参数?

    delphi - 自动登录(网络浏览器)