如何仅扩展到树视图的第二级

时间:2014-12-08 13:36:47

标签: delphi treeview delphi-xe6

例如:

    - link 1
    -- link 1.1
    --- link 1.1.1(only)
    ---- link 1.1.1.1 (not expand)
    -- link 1.2
    --- link 1.2.1 (only)
    ---- link 1.2.1.1 (not expand)

我只能扩展链接1.1,链接1.2 ......如何?

1 个答案:

答案 0 :(得分:2)

没有用于在特定级别上扩展多个项目或项目的内置功能,因此没有其他方法可以遍历项目。在所有二级项目上调用Expand方法。同样适用于所有第一级项目,否则将不会显示第二级项目。其Recurse参数应为False,以便不会扩展可能的第三级或更深级别。

有两种方法可以遍历TreeView的项目:按项目索引和按节点。通常,对TreeView项的操作最好由Node完成,因为Items属性的getter遍历所有Items 以查找具有特定索引的单个Item。但是,TTreeNodes缓存最后检索的项目,因此通过将循环索引递增1,将最小化伤害。

然后简单的解决方案变为:

procedure ExpandTreeNodes(Nodes: TTreeNodes; Level: Integer);
var
  I: Integer;
begin
  Nodes.BeginUpdate;
  try
    for I := 0 to Nodes.Count - 1 do
      if Nodes[I].Level < Level then
        Nodes[I].Expand(False);
  finally
    Nodes.EndUpdate;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExpandTreeNodes(TreeView1.Items, 2);
end;

请注意,Items属性的getter仍然会被调用两次。尽管有缓存机制,我认为仍然应该避免这种情况:

procedure ExpandTreeNodes(Nodes: TTreeNodes; Level: Integer);
var
  I: Integer;
  Node: TTreeNode;
begin
  Nodes.BeginUpdate;
  try
    for I := 0 to Nodes.Count - 1 do
    begin
      Node := Nodes[I];
      if Node.Level < Level then
        Node.Expand(False);
    end;
  finally
    Nodes.EndUpdate;
  end;
end;

但是你不妨使用:

procedure ExpandTreeNodes(Nodes: TTreeNodes; Level: Integer);
var
  Node: TTreeNode;
begin
  Nodes.BeginUpdate;
  try
    Node := Nodes.GetFirstNode;
    while Node <> nil do
    begin
      if Node.Level < Level then
        Node.Expand(False);
      Node := Node.GetNext;
    end;
  finally
    Nodes.EndUpdate;
  end;
end;

这仍然遍历了所有项目。好的,只有一次。但是如果你有一个非常大的和/或深度的树,并且你想要最高的效率,并且你不关心可读性,或者你只是想尝试使用TreeView的节点来获得乐趣,那么使用:

procedure ExpandTreeNodes(Nodes: TTreeNodes; Level: Integer);
var
  Node: TTreeNode;
  Next: TTreeNode;
begin
  if Level < 1 then
    Exit;
  Nodes.BeginUpdate;
  try
    Node := Nodes.GetFirstNode;
      while Node <> nil do
      begin
        Node.Expand(False);
        if (Node.Level < Level - 1) and Node.HasChildren then
          Node := Node.GetFirstChild
        else
        begin
          Next := Node.GetNextSibling;
          if Next <> nil then
            Node := Next
          else
            if Node.Level > 0 then
              Node := Node.Parent.GetNextSibling
            else
              Node := Node.GetNextSibling;
        end;
      end;
  finally
    Nodes.EndUpdate;
  end;
end;