Delphi TTreeView:通过索引获取根节点数和根节点?
Delphi TTreeView: get root node count and root node by index?
每个TTreeNode
都可以用Node.Count
给我它的直接children数,我可以用Node[Index]
通过索引得到任何child。
我正在搜索和搜索但是对于根节点来说这似乎是不可能的??我真的必须自己数吗?如果是,那么最优雅的方法是什么?
我期待一些隐藏的root-root-item,其中只有所有根节点作为children,能够以相同的方式对待所有类型的节点,即对于为所有节点执行某些操作的递归函数,这不是很有帮助吗?
你说得对,TTreeView
应该有这个,但没有,而且我没有看到一个好的理由。但是,这里有一些想法需要考虑:
TTreeView
中使用的数据结构不直接支持直接计数children或通过索引访问它们,因为它是一个链表,每个节点链接到它的parent、它的下一个和上一个兄弟,以及它的第一个 child.
为了您的方便,TTreeNode
object 能够为您提供您想要的,但为此它必须遍历链并计数。
这也意味着,在 for-loop 中访问所有 children 无论如何都不是一个好主意,就像在你提到的递归函数中一样 - 它不一定是循环中的循环。
相反,直接使用 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]));
每个TTreeNode
都可以用Node.Count
给我它的直接children数,我可以用Node[Index]
通过索引得到任何child。
我正在搜索和搜索但是对于根节点来说这似乎是不可能的??我真的必须自己数吗?如果是,那么最优雅的方法是什么?
我期待一些隐藏的root-root-item,其中只有所有根节点作为children,能够以相同的方式对待所有类型的节点,即对于为所有节点执行某些操作的递归函数,这不是很有帮助吗?
你说得对,TTreeView
应该有这个,但没有,而且我没有看到一个好的理由。但是,这里有一些想法需要考虑:
TTreeView
中使用的数据结构不直接支持直接计数children或通过索引访问它们,因为它是一个链表,每个节点链接到它的parent、它的下一个和上一个兄弟,以及它的第一个 child.
为了您的方便,TTreeNode
object 能够为您提供您想要的,但为此它必须遍历链并计数。
这也意味着,在 for-loop 中访问所有 children 无论如何都不是一个好主意,就像在你提到的递归函数中一样 - 它不一定是循环中的循环。
相反,直接使用 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]));