how to expand only to the second level of the treeview

↘锁芯ラ 提交于 2019-12-23 04:36:24

问题


Ex.:

    - 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)

I can expand only link 1.1, link 1.2... how?


回答1:


There is no build-in functionality for expanding multiple items or items on a specific level, so there is no other way then traversing through the items. Call the Expand method on all second level items. As well on all first level items, otherwise the second level items will not be shown. Its Recurse parameter should be False in order not to expand a possibly third or deeper level.

There are two ways to traverse through a TreeView's items: by Item index and by Node. Normally, operations on a TreeView's items are preferably done by Node, because the Items property's getter traverses through all Items to find a single Item with a specific index. However, TTreeNodes caches the last retrieved item, thus by incrementing the loop Index with 1, harm will be minimized.

The easy solution then becomes:

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;

Note that the Items property's getter is still called twice. Despite the caching mechanism, I think this still should be avoided:

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;

But then you might as well use:

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;

This still traverses áll Items. Ok, just once. But if you have a really big and/or deep tree, and you want maximum efficiency, and you do not care about readability, or you just want to experiment with a TreeView's Nodes for fun, then use:

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;


来源:https://stackoverflow.com/questions/27359264/how-to-expand-only-to-the-second-level-of-the-treeview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!