我需要一个可以与 Virtual Treeview 一起使用的树实现,它不会消耗太多内存,易于使用,并且与 VT 一样快(也就是说,当我将数据存储在 VT 本身时)
我尝试了 Linas 的 svTree - 它易于使用,但不像我希望的那样快速和内存友好。
另外,只想指出我的应用程序将管理数千个节点。:)
你推荐什么免费图书馆?您能否构建一个如何与 Virtual Treeview 一起使用的最小演示?
我需要一个可以与 Virtual Treeview 一起使用的树实现,它不会消耗太多内存,易于使用,并且与 VT 一样快(也就是说,当我将数据存储在 VT 本身时)
我尝试了 Linas 的 svTree - 它易于使用,但不像我希望的那样快速和内存友好。
另外,只想指出我的应用程序将管理数千个节点。:)
你推荐什么免费图书馆?您能否构建一个如何与 Virtual Treeview 一起使用的最小演示?
查看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;
您不需要控件或库来记住数据。您需要提出一个适合您需求的数据结构。最后一步是使用 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 控件中。
听起来您有非常具体的需求,所以我觉得不会有一个完整的解决方案来满足您的确切要求。
我的第一个建议是使用数据库。它具有我(认为)您需要的所有功能,以及强大且非常快速的额外好处。显然,您将不得不编写一些例程来处理数据的添加/删除/插入/编辑等。关系数据库将能够存储您的类别之间的所有关系,并轻松更改记录之间的关系(节点)。花时间学习如何存储分层数据,然后了解节点之间的关系。精心设计的数据库将为您提供项目的所有细节。MySQL 是免费的,而且使用起来非常简单。占地面积小,但速度非常快。看看这篇文章,让您思考如何以关系方式存储树数据结构:关系树数据结构.
话虽如此,我不太确定这就是你要找的东西。
数据库如何存储树的示例:
如果数据库不可行,那么我鼓励您编写自己的课程。只有您知道您的数据是如何管理和组合在一起的。因此,您可以编写您的树需要一起操作和组合的确切功能。从查看 TObjectList 开始。创建为每个节点存储数据的类对象。然后,您可以创建这些对象的列表来保存所有节点。编写方法来模拟在树上执行的用户操作,例如添加、更新、移动等。这可能需要一些时间,但它确实会帮助您学习,并使您作为应用程序设计者受益。当你遇到困难时,边走边问。
一些有趣的非可视化树列在以下答案中: Delphi non-visual TTree implementation
其中之一可能适合您的需求。