【问题标题】:Delphi TTreeView: get root node count and root node by index?Delphi TTreeView:按索引获取根节点计数和根节点?
【发布时间】:2019-11-14 18:38:58
【问题描述】:

每个TTreeNode 都可以使用Node.Count 给我它的直接子代数,我可以使用Node[Index] 按索引获取任何子代。

我正在搜索和搜索,但似乎这对于根节点来说是不可能的??我真的必须自己数数吗?如果是的话,最优雅的方式是什么?

我期待一些隐藏的 root-root-item 它只是将所有 根节点 作为子节点,这对能够处理各种问题没有帮助吗节点数相同,即递归函数对所有节点做某事?

【问题讨论】:

  • TTreeView.Items 怎么样?
  • 它通过absolute索引返回所有节点,@MartynA
  • 当然,但它的一项不是带有 Nil .parent 的 TreeNode 吗?
  • 当然我可以从那里得到必要的信息,只是感觉有点麻烦,与子节点相比,@MartynA
  • 其中一个节点将为 IsFirstNode 返回 true。从 OLH “IsFirstNode 为第一个节点返回 true,没有父节点或前一个兄弟节点。”

标签: delphi treeview delphi-10-seattle


【解决方案1】:

你说得对,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]));

【讨论】:

  • 我会调用 GetFirstNode 并使用 GetNextSibling 循环。
  • @SertacAkyuz,正确,我无意中查看了 Vcl.ComCtrls,其中 TTreeNode.GetItem 是使用 GetFirstChild 和 GetNextChild 完成的...已编辑。
  • 我试图问一个好问题,在写它的同时,@MartynA,我继续调查,然后不想把它扔掉......所以我发布了它,已经假设我会自己写答案:) 我以前做过这个,似乎有些人不喜欢它。我真的很想知道为什么...
  • 我完全不介意人们回答自己的问题,事实上,我希望在没有其他人发布答案的情况下会有更多人这样做。在这种情况下,我只是好奇你的措辞你回答的方式,称自己为“你”,而不是仅仅说出“进一步考虑,我相信以下回答我的问题......”这样的话。就是这样……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多