如何在动态更新的树中使用虚拟树视图?

时间:2019-09-25 08:58:32

标签: delphi virtualtreeview

我正在使用Delphi XE3和Virtual TreeView。

我想使用Virtual TreeView来实现一棵树,当单击“开始”按钮时,该程序将递归搜索驱动器下的所有文件和文件夹,然后将它们一个一个地添加到树中,就像Windows资源管理器一样。 / p>

仔细阅读帮助文档中的“虚拟范例”后,我知道我不能使用AddChild或InsertNode,因为它们仅出于兼容性目的。应该使用OnInitNode和OnInitChildren初始化节点。

但是对于我的情况,使用虚拟范例确实很困难。目前,我可以找出一种算法:

  1. 定义一个内部数据结构TMyInternalNode,用于存储一棵树内部节点的数据以及内部节点之间的关系,例如父,子,兄弟等。

  2. 在OnInitNode和OnInitChildren事件中。尝试通过节点的级别和其他节点之间的关系查找节点的位置。然后为该节点找到相应的内部节点(这可能会有些困难,有时可能会遍历整个内部节点树以找到正确的内部节点。找到正确的内部节点后,请使用内部节点数据初始化该节点。

此算法似乎很复杂且耗时。有没有更好的方法来实现这种情况?

1 个答案:

答案 0 :(得分:1)

虚拟范例非常有趣,有用。但是现实是您实际上并不想使用虚拟范式。

虚拟模型的目的实际上是在用户要求之前才获取任何数据。

如果首先从C:驱动器的根目录中获取文件夹列表:

  • ?英特尔
  • ?MSOCache
  • ?PerfLogs
  • ?程序文件
  • ?Progream文件(x86)
  • ?ProgramData
  • ?用户
  • ?Windows

要点是您在此停留虚拟范例中的目标是仅根据需要填充树

如果用户随后选择扩展节点,则那个是在您获取子节点时:

  • ?英特尔
  • ?MSOCache
  • ?PerfLogs
  • ?程序文件
  • ?Progream文件(x86)
  • ?ProgramData
  • ?用户
    • ?艾伦
    • ?大卫
    • ?伊恩
  • ?Windows

然后您可以:

  • 直接依靠node.Index来确定每个节点代表什么
  • 或在每个PVirtualNode中存储任意数据,以帮助您将其链接到基础数据

但是您并没有真正做到这一点:

  

单击“开始”按钮时,程序将递归搜索驱动器下的所有文件和文件夹,然后将它们一个一个地添加到树中,就像Windows资源管理器一样。

您正在加载所有内容,并希望显示所有数百万个文件。

现在,这绝对没有错。虚拟树几乎可以立即创建一百万个节点。太棒了。我将定期加载100,000行客户,发票,销售订单等。然后用户可以Ctrl+F,或将行导出到Excel。

但是在您的情况下,它不是“虚拟” ;因为您要为50万个文件 -up-front 分配内存。

虚拟范例的优点是节省内存。

  • 您只是,有50万个节点,
  • 这棵树会假装,有50万个节点,
  • 但实际上并没有分配50万个节点的内存

不是虚拟的也可以

对于您来说,是虚拟的也是可以的。如果您从根本上希望加载所有内容,而不管用户已扩展,滚动或看到了什么,那么就很好。然后您可以使用:

  • AddChild

但是您还意识到,预先分配450,409个TMyFileInfo对象与节省内存直到需要时的想法背道而驰。

虚拟版本

您可以将其虚拟化,方法是仅为用户打开的文件夹获取子项。但这有缺点。很多时候,我想要该程序为我在后台获取所有内容。