2

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
  • 1
    You should always add the generic delphi tag to your delphi related questions to have the correct syntax highlighter and more attention on your question. Commented Dec 8, 2014 at 21:25

1 Answer 1

3

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; 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.