每个TTreeNode
都可以使用Node.Count
来给我直接子的数量,我可以使用Node[Index]
来按索引来获取任何子代。
我正在搜索,但是似乎对于根节点是不可能的??我真的必须自己数一下吗?如果是的话,做到这两种方式的最优雅的方法是什么?
我期望某些隐藏的 root-root-item 只是所有 root节点的子元素,这对处理各种问题不会有帮助的节点是相同的,即对于一个递归函数对所有节点做某事?
答案 0 :(得分:3)
您是对的,TTreeView
应该有这个,但事实并非如此,我看不出有充分的理由。但是,以下是一些需要考虑的想法:
TTreeView
中使用的数据结构不直接支持对直接子项进行计数或按索引访问它们,因为它是一个链表,其中每个节点都链接到其父节点,其下一个和上一个兄弟节点及其子节点。第一个孩子。
为方便起见,TTreeNode
对象可以为您提供所需的内容,但为此必须遍历整个链并进行计数。
这也意味着,在for循环中访问所有子级都不是一个好主意,就像您提到的递归函数一样-不必要是循环中的循环。
相反,直接使用TreeView.Items.GetFirstNode
(或MyParentNode.getFirstChild
)遍历整个链,然后使用Node:= Node.getNextSibling
进行while循环(这对于递归函数也非常有用)。
建议:查看 Vcl.ComCtrls 中的实现。从那里,如果您仍然需要它,您还可以调整所要求的两个最优雅的功能:)
type
TTreeViewClassHelper = class helper for TTreeView
function GetRootCount: Integer;
function GetRootItem(Index: Integer): TTreeNode;
end;
function TTreeViewClassHelper.GetRootCount: Integer;
var
Node: TTreeNode;
begin
Result:= 0;
Node:= Items.GetFirstNode;
while Assigned(Node) do begin
Inc(Result);
Node:= Node.getNextSibling;
end;
end;
function TTreeViewClassHelper.GetRootItem(Index: Integer): TTreeNode;
begin
Result:= Items.GetFirstNode;
while Assigned(Node) and (Index > 0) do begin
Result:= Result.getNextSibling;
Dec(Index);
end;
end;
并且只是为了演示您应该如何不这样做;-)
for I:= 0 to TreeView.GetRootCount - 1 do
with TreeView.GetRootItem(I) do
Memo.Lines.Add(string.Join(#9, [AbsoluteIndex, Index, Text]));