问题
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