5

我需要一个可以与 Virtual Treeview 一起使用的树实现,它不会消耗太多内存,易于使用,并且与 VT 一样快(也就是说,当我将数据存储在 VT 本身时)

我尝试了 Linas 的 svTree - 它易于使用,但不像我希望的那样快速和内存友好。

另外,只想指出我的应用程序将管理数千个节点。:)

你推荐什么免费图书馆?您能否构建一个如何与 Virtual Treeview 一起使用的最小演示?

4

4 回答 4

3

查看rmControls库中的rmTreeNonView组件。

多年来,我们一直在使用该树的修改版本作为数据容器。它是免费的、快速的、非可视化的、带有源代码的,并且很容易上手,因为几乎 100% 重复了 TTreeView 的方法和属性,并且添加了一些自己的方法——特别是基于哈希的快速树搜索节点路径。

我怀疑这家公司已经不再营业了 (http://www.mills-enterprise.ca),但是许多 Delphi 下载站点上都提供了包含源代码的 rmControls 包。

编辑:

下面是一些代码,展示了如何从 VTV 的节点指向另一个树结构中的节点......希望我已经包含了足够的代码让您了解发生了什么。TmwDataTreeNode 是 TTreeNonView 后代的一个节点。请注意,当 PopulateVT 方法完成时,每个 TNodeData 的 ContextNode 字段都指向源数据容器树中的一个节点。请注意,此方法没有利用 VTV 的虚拟特性,这可能更适合您的情况。

type
      //Virtual tree record stuff
  PNodeData = ^TNodeData;
  TNodeData = record
  public
    NodeSelf: PVirtualNode;         //Ptr to our own VT node...needed?
    ContextNode: TmwDataTreeNode;        //ptr to our corresp node of data tree
    GridRecordIndex: integer;      //Grid.RecordIndex of our corresp Alloc formula.
  end;


procedure T_fmExplAllocOut.PopulateVT;
{ Load data to the DragDrop treeview. }
var
  n: TmwDataTreeNode;        //Pointer to a node of my customized TTreeNonView
begin
  VT.NodeDataSize := SizeOf(TNodeData);
  VT.BeginUpdate;
  vtsChangeFontSize(VT, Self.Font.Size);     //Set Tree Font.Size & DefaultNodeHeight
      //Add DragDrop Tree nodes
  n := AllocController.SnapContext.Tree.Items.GetFirstNode;
  while n <> nil do begin
    AddVTNode(nil, n);              //nil=parent node of top-level VT nodes
    n := n.GetNextSibling;
  end;
  VT.FullExpand;
  VT.EndUpdate;
end;


procedure T_fmExplAllocOut.AddVTNode(VTParentNode: PVirtualNode; n: TmwDataTreeNode);
{ Recursively add n & its children to VT. }
var
  NodeData: PNodeData;
  VTNode: PVirtualNode;
begin
  if (n = nil) or not NodeInIncludeFilter(n) then
    exit;
      //Add this node
  VTNode := VT.AddChild(VTParentNode);
  NodeData := VT.GetNodeData(VTNode);
  VT.ValidateNode(VTNode, False);        //else OnFreeNode won't get called
  with NodeData^ do begin
    NodeSelf :=         VTNode;
    ContextNode :=      n;
    GridRecordIndex := -1;
  end;
      //Add child nodes
  n := n.GetFirstChild;
  while n <> nil do begin
    AddVTNode(VTNode, n);            //Pass our added node as Parent
    n := n.GetNextSibling;
  end;
end;
于 2011-05-09T18:08:13.147 回答
3

您不需要控件或库来记住数据。您需要提出一个适合您需求的数据结构。最后一步是使用 VTV 或任何其他控件来显示您的数据结构。暂时停止考虑 GUI,想想你想如何构建你的数据结构。想想设计模式和老式编程、链接列表、数组、队列、哈希列表/字典、红/黑树等。在搜索、遍历、添加的速度和内存使用方面,每个都有自己的优缺点。有图书馆(如http://www.boyet.com/FixedArticles/EZDSL.html) 具有基本的构建块,但你必须弄清楚你想要什么。如果您卡在那里,我建议您提出一个新问题并指定数据结构的要求。您可能想阅读https://sites.google.com/site/igetfreebook/The-Tomes-of-Delphi-Algorithms-and-Data-Structures

如果您的问题是关于还存储数据的 GUI 控件,那么我想知道您为什么不想使用 VTV。也许其他控件更容易,但从设计的角度来看,它们并没有更好。您仍在将数据存储在 GUI 控件中。

于 2011-05-09T20:15:46.063 回答
2

听起来您有非常具体的需求,所以我觉得不会有一个完整的解决方案来满足您的确切要求。

我的第一个建议是使用数据库。它具有我(认为)您需要的所有功能,以及强大且非常快速的额外好处。显然,您将不得不编写一些例程来处理数据的添加/删除/插入/编辑等。关系数据库将能够存储您的类别之间的所有关系,并轻松更改记录之间的关系(节点)。花时间学习如何存储分层数据,然后了解节点之间的关系。精心设计的数据库将为您提供项目的所有细节。MySQL 是免费的,而且使用起来非常简单。占地面积小,但速度非常快。看看这篇文章,让您思考如何以关系方式存储树数据结构:关系树数据结构.

话虽如此,我不太确定这就是你要找的东西。

数据库如何存储树的示例:

来自数据库的样本树

如果数据库不可行,那么我鼓励您编写自己的课程。只有知道您的数据是如何管理和组合在一起的。因此,您可以编写您的树需要一起操作和组合的确切功能。从查看 TObjectList 开始。创建为每个节点存储数据的类对象。然后,您可以创建这些对象的列表来保存所有节点。编写方法来模拟在树上执行的用户操作,例如添加、更新、移动等。这可能需要一些时间,但它确实会帮助您学习,并使您作为应用程序设计者受益。当你遇到困难时,边走边问。

于 2011-05-10T00:47:01.200 回答
0

一些有趣的非可视化树列在以下答案中: Delphi non-visual TTree implementation

其中之一可能适合您的需求。

于 2011-05-10T01:20:04.390 回答