我该如何为TTreeNodes实现GetLastNode?

Dav*_*nan 3 delphi

当我需要在a中找到第一个节点时TTreeView,我打电话TTreeNodes.GetFirstNode.但是,我有时需要在树中找到最后一个节点,并且没有相应的TTreeNodes.GetLastNode功能.

我不想使用,Items[Count-1]因为这导致整个树走了Result := Result.GetNext.当然,这仅在树视图具有大量节点时才有意义.我完全理解虚拟容器控件的优点,但我还没有切换到Virtual TreeView.

到目前为止,我已经提出以下建议:

function TTreeNodes.GetLastNode: TTreeNode;
var
  Node: TTreeNode;
begin
  Result := GetFirstNode;
  if not Assigned(Result) then begin
    exit;
  end;
  while True do begin
    Node := Result.GetNextSibling;
    if not Assigned(Node) then begin
      Node := Result.GetFirstChild;
      if not Assigned(Node) then begin
        exit;
      end;
    end;
    Result := Node;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

谁能:

  1. 在我的逻辑中发现一个缺陷?
  2. 建议改进?

编辑1

我不愿意保留自己的节点缓存.我一直这样做直到最近,但发现一些难以跟踪非常间歇性的AV,我认为这必定是由于我的缓存不同步.显然,一个解决方案是让我的缓存同步代码正常工作,但我厌恶缓存,因为很难跟踪错误时出现的错误.

NGL*_*GLN 6

虽然我不是非退出纯粹主义者,但我认为如果在没有退出的情况下可行,同时保持可读性不变,则可能更喜欢该选项.

所以这里是完全相同的代码,因为我不认为你可以通过任何其他方式(更快)到终端节点,但没有退出和稍微更紧凑:

function TTreeNodes.GetLastNode: TTreeNode;
var
  Node: TTreeNode;
begin
  Node := GetFirstNode;
  Result := Node;
  if Result <> nil then
    repeat
      Result := Node;
      if Node <> nil then
        Node := Result.GetNextSibling;
      if Node = nil then
        Node := Result.GetFirstChild;
    until Node = nil;
end;
Run Code Online (Sandbox Code Playgroud)