在树视图中所有分支的末尾添加一个节点

Add a node at the end of all branches in a treeview

for j:=0 to TreeView1.Items.Count-1 do
 if (not(CNode.HasChildren) then
 begin
  CNode:=TreeView1.Items[j];
  CNode:=TreeView1.Items.AddChild(Cnode,'xxxx');
 end;

显然不起作用,因为树中的项目数量每一步都在增加。

Imo,如果你递归地这样做是最干净的,如

procedure TForm1.AddChildren(ATreeView: TTreeView);

  procedure ProcessNode(Node : TTreeNode);
  var
    NewNode : TTreeNode;
  begin
    while Node <> Nil do begin
      if Node.HasChildren then
        ProcessNode(Node.getFirstChild)
      else
        NewNode := ATreeView.Items.AddChild(Node, 'Child of ' + Node.Text);
      Node := Node.getNextSibling;  
    end;
  end;

begin
  ProcessNode(ATreeView.Items[0]);
  ATreeView.FullExpand;
end;

,最好在对 Items 的调用之间括起来。BeginUpdate/EndUpdate。这样,您就可以避免 TreeView.Items.Count 更改时出现的问题。

如果您出于某种原因必须坚持使用 TreeView.Items,您可以这样做:

procedure TForm1.AddChildren(ATreeView: TTreeView);
var
  List : TList;
  i : Integer;
  Node,
  NewNode : TTreeNode;
begin
  List := TList.Create;
  try
    ATreeView.Items.BeginUpdate;
    for i := 0 to ATreeView.Items.Count - 1 do
      List.Add(ATreeView.Items[i]);
    for i := 0 to List.Count - 1 do begin
      Node := TTreeNode(List.Items[i]);
      if not Node.HasChildren then begin
        NewNode := ATreeView.Items.AddChild(Node, 'Child of ' + Node.Text);
      end;
      Node.Expand(True);
    end;
  finally
    ATreeView.Items.EndUpdate;
    List.Free;
  end;
end;

显然,这可以通过创建树节点的 TList 然后迭代它来添加新的子节点来实现。

您可以通过仅将无子节点添加到列表中来提高效率,但随后正确地完全扩展树 - 如果这是您想要的 - 需要一个额外的步骤:

procedure TForm1.AddChildren(ATreeView: TTreeView);
[...]
    for i := 0 to ATreeView.Items.Count - 1 do begin
      if not ATreeView.Items[i].HasChildren then
        List.Add(ATreeView.Items[i]);
    end;
    for i := 0 to List.Count - 1 do begin
      Node := TTreeNode(List.Items[i]);
      if not Node.HasChildren then begin
        NewNode := ATreeView.Items.AddChild(Node, 'Child of ' + Node.Text);
      end;
    ATreeView.FullExpand;
  [...]
end;