我有一个从第三方项目文件填充的对象列表。设计此文件的方式是每个项目都处于层次结构的“级别”。所以第一个项目在0级,所有子项目都在1级,依此类推。
举个例子:
1. Node 1 (Level 0)
2. Node 1.1 (Level 1)
3. Node 1.2 (Level 1)
4. Node 1.3 (Level 1)
5. Node 1.3.1 (Level 2)
6. Node 1.4 (Level 1)
7. Node 2 (Level 0)
8. Node 2.1 (Level 1)
9. Node 2.1.1 (Level 2)
10. Node 3 (Level 0)
这会产生如下的层次结构:
- Node 1
--- Node 1.1
--- Node 1.2
--- Node 1.3
----- Node 1.3.1
--- Node 1.4
- Node 2
--- Node 2.1
----- Node 2.1.1
- Node 3
我的问题是弄清楚如何根据每个列出的对象的这些“级别”属性将此结构填充到VCL TTreeView
中。如果我设计了这个第三方文件结构,我会使用父属性而不是级别属性。
此列表中的对象可以像这样迭代:
var
I: TMyItem;
N: TTreeNode;
begin
for X := 0 to MyList.Count - 1 do begin
I := MyList[X];
//TMyItem has property "Level" which specifies hierarchy
// as well as "Title" property for the node's caption
//How to create node based on Level?
N.Data := I;
end;
end;
基于这种结构,我如何在树状视图中填充它?
答案 0 :(得分:8)
创建一个列表,其中包含每个级别的最新父节点。最初此列表将为空。
现在走线性列表。每当您将N级项目添加到列表中时,您都会执行以下操作:
你需要处理N = 0的情况,上面的算法要求你在-1级提出最新的父级,无论这意味着什么。您的树是否有整体根节点?如果是这样,那么根据定义,级别-1的最新父级是根节点。否则,如果没有根节点,您将需要执行树视图组件在顶层添加节点所需的任何内容,而不是另一个节点的子节点。
假设没有根节点,那么代码将如下所示:
var
Item: TItem;
LatestParents: TList<TTreeNode>;
Parent, NewNode: TTreeNode;
begin
LatestParents := TList<TTreeNode>.Create;
try
LatestParents.Add(nil);
for Item in Items do
begin
Parent := LatestParents[Item.Level];
NewNode := TreeView.Items.AddChild(Parent, Item.Text);
LatestParents.Count := Max(LatestParents.Count, Item.Level+2);
LatestParents[Item.Level+1] := NewNode;
end;
finally
LatestParents.Free;
end;
end;
如果您的代码可能遇到格式错误的树形描述,您可能需要对代码进行一些错误检查。例如,如果您遇到的第一个节点没有级别0,则此代码将失败。
答案 1 :(得分:7)
尝试这样的事情:
var
Item: TMyItem;
Node: TTreeNode;
NodeLevel: Integer;
X: Integer;
begin
Node := nil;
NodeLevel := 0;
for X := 0 to MyList.Count-1 do
begin
Item := MyList[X];
if (Node = nil) or (Item.Level <= 0) then
begin
Node := TreeView1.Items.AddObject(nil, Item.Text, Item);
NodeLevel := 0;
end
else if Item.Level = NodeLevel then
begin
Node := TreeView1.Items.AddObject(Node, Item.Text, Item);
end else
begin
while Item.Level <= NodeLevel do
begin
Node := Node.Parent;
Dec(NodeLevel);
end;
Node := TreeView1.Items.AddChildObject(Node, Item.Text, Item);
Inc(NodeLevel);
end;
// set Node properties as needed...
end;
end;