Recent

Author Topic: Treeview - expanding parents of node.  (Read 905 times)

teresa

  • Guest
Treeview - expanding parents of node.
« on: May 24, 2024, 12:20:54 am »
In a program there is  aTTreeview, with just two "levels"  - roughly diagrammed:
A
|__A1
|__A2
B
|__B1
|__B2
C
|__C1

Normally only one of the top level nodes (A,B,C) is expanded and one of the second-level nodes below that one generates a form full of data.

Now I have had to add a routine to jump to a specific second-level node. Done But I have been unable to leave the tree  with its parent node alone expanded - so if B2 is chosen, B should be expanded, A and C not.

I thought that collapsing the tree and then using currentnode.expandparents would do the job, but that leaves the tree collapsed.

Any help greatly appreciated!
Thanks
T.

jamie

  • Hero Member
  • *****
  • Posts: 6301
Re: Treeview - expanding parents of node.
« Reply #1 on: May 24, 2024, 01:36:28 am »
Code: Pascal  [Select][+][-]
  1. TreeView1.Items.TopLvlItems[0].Expanded := False;
  2.  

Experimenting with a second main node, I can do the above in a button click and the second main node remains open and un-disturb with the sub nodes also open?

 Unless I misunderstood you, you are trying to collapse all other main nodes when working with a particular main node with its sub nodes without them closing?

 If that is the case, what I did above works and if it does not for you, you may want us to know the OS target?

 some widgets need to be written where others are native OS controls. In the case of windows, it's a native control.

 Please advise me if I mis understood you?


The only true wisdom is knowing you know nothing

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Treeview - expanding parents of node.
« Reply #2 on: May 24, 2024, 02:01:51 am »
I am unsure how you meant it. I've prepared a method that find a node by its display name, if found all gets collapsed and everything thats needed to be expanded to display the node will be.
Code: Pascal  [Select][+][-]
  1. function ExpandToNode(const ATreeView: TTreeView; const ANodeName: string): Boolean;
  2.   procedure NodesCollapse(const ATreeView: TTreeView);
  3.   var
  4.     LNode: TTreeNode;
  5.   begin
  6.     LNode := ATreeView.Items.GetFirstNode;
  7.     while Assigned(LNode) do
  8.       begin
  9.         LNode.Collapse(False);
  10.         LNode := LNode.GetNext;
  11.       end;
  12.   end;
  13.   procedure NodesExpand(const ATreeNode: TTreeNode);
  14.   var
  15.     LNode: TTreeNode;
  16.   begin
  17.     LNode := ATreeNode;
  18.     while Assigned(LNode) do
  19.       begin
  20.         LNode.Expand(False);
  21.         LNode := LNode.Parent;
  22.       end;
  23.   end;
  24. var
  25.   LNode: TTreeNode;
  26. begin
  27.   Result := False;
  28.   LNode := ATreeView.Items.GetFirstNode;
  29.   while Assigned(LNode) do
  30.     begin
  31.       if SameText(LNode.Text, ANodeName) then
  32.         begin
  33.           NodesCollapse(ATreeView);
  34.           NodesExpand(LNode);
  35.           ATreeView.Selected := LNode;
  36.           Result := True;
  37.           Break;
  38.         end;
  39.       LNode := LNode.GetNext;
  40.     end;
  41. end;
« Last Edit: May 24, 2024, 02:55:46 am by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

teresa

  • Guest
Re: Treeview - expanding parents of node.
« Reply #3 on: May 24, 2024, 03:50:27 am »
I have been too terse.

This is Linux, gtk2, Lazarus 3.2

The code locates a required node, such as B2. The desired behaviour is then to have the tree collapsed except for the parent of B2, i.e. B, so it looks like

  A
  B
   |_  B1
   |_  B2
  C

I see plenty of ideas to test in the replies so far - many thanks, I shall try them and get back.

T.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Treeview - expanding parents of node.
« Reply #4 on: May 24, 2024, 09:58:22 am »
The code locates a required node, such as B2. The desired behaviour is then to have the tree collapsed except for the parent of B2, i.e. B, so it looks like
That suits my method perfect besides if its wanted that B2 expands or not.
Code: Pascal  [Select][+][-]
  1. if ExpandToNode(TreeView1, 'B2') then ...
This is Linux, gtk2, Lazarus 3.2
I hope that gtk2 support and work this time same way as it does on the windows widgetset.

The only problem where I am aware about but have no real solution would be if two nodes named same way, only the first found will be computed.
Tested with a TTreeView that I just throw on form, added some nodes, run my code over it, without changing any option to the TreeView.

Updated with arguments to control if "B2" should be automagical expanded or just all parent nodes and if "B2" should be selected.
Code: Pascal  [Select][+][-]
  1. function ExpandToNode(const ATreeView: TTreeView; const ANodeName: string; const AExpandCurrent: Boolean = True; const APreSelect: Boolean = True): Boolean;
  2.   procedure NodesCollapse(const ATreeView: TTreeView);
  3.   var
  4.     LNode: TTreeNode;
  5.   begin
  6.     LNode := ATreeView.Items.GetFirstNode;
  7.     while Assigned(LNode) do
  8.       begin
  9.         LNode.Collapse(False);
  10.         LNode := LNode.GetNext;
  11.       end;
  12.   end;
  13.   procedure NodesExpand(const ATreeNode: TTreeNode; const AExpandCurrent: Boolean = True);
  14.   var
  15.     LNode: TTreeNode;
  16.   begin
  17.     if AExpandCurrent then
  18.       LNode := ATreeNode
  19.     else
  20.       LNode := ATreeNode.Parent;
  21.     while Assigned(LNode) do
  22.       begin
  23.         LNode.Expand(False);
  24.         LNode := LNode.Parent;
  25.       end;
  26.   end;
  27. var
  28.   LNode: TTreeNode;
  29. begin
  30.   Result := False;
  31.   LNode := ATreeView.Items.GetFirstNode;
  32.   while Assigned(LNode) do
  33.     begin
  34.       if SameText(LNode.Text, ANodeName) then
  35.         begin
  36.           NodesCollapse(ATreeView);
  37.           NodesExpand(LNode, AExpandCurrent);
  38.           if APreSelect then
  39.             ATreeView.Selected := LNode;
  40.           Result := True;
  41.           Break;
  42.         end;
  43.       LNode := LNode.GetNext;
  44.     end;
  45. end;
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

teresa

  • Guest
Re: Treeview - expanding parents of node.
« Reply #5 on: May 24, 2024, 10:26:12 am »
Wow - thank you for all that work.

I am sure that I can use this code, adapting the test for deciding that the node is found.

I greatly appreciate this.
T,

jamie

  • Hero Member
  • *****
  • Posts: 6301
Re: Treeview - expanding parents of node.
« Reply #6 on: May 26, 2024, 05:40:37 pm »
I must not be understanding something or else there is an issue with the Linux port of the control?

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   N:TTreeNode;
  4. begin
  5.   N:= TreeView1.Items.FindNodeWithText('Item5'); //Other ways to find a node.
  6. if N<>Nil Then
  7.   Begin
  8.     TreeView1.FullCollapse;
  9.     N.ExpandParents;
  10.     N.Selected := True;
  11.   end;
  12. end;                                                
  13.  

Many ways to find a node in the list but using a simple test, this works perfectly on windows.

Is it possible you need to refresh the list ? "Repaint, Update, Application.ProcessMessages" etc
The only true wisdom is knowing you know nothing

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Treeview - expanding parents of node.
« Reply #7 on: May 26, 2024, 06:31:15 pm »
I must not be understanding something or else there is an issue with the Linux port of the control?

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   N:TTreeNode;
  4. begin
  5.   N:= TreeView1.Items.FindNodeWithText('Item5'); //Other ways to find a node.
  6. if N<>Nil Then
  7.   Begin
  8.     TreeView1.FullCollapse;
  9.     N.ExpandParents;
  10.     N.Selected := True;
  11.   end;
  12. end;                                                
  13.  

Many ways to find a node in the list but using a simple test, this works perfectly on windows.

Is it possible you need to refresh the list ? "Repaint, Update, Application.ProcessMessages" etc
Only difference between our snippets is that I iterate to update everywhere to set the wanted properties while you call built-in methods that might do same. (I have not watched what they do)
In past I had some troubles but forget in what context with the TTreeView component (Delphi) so I am used to do it like I showed.
Within my method no update/repaint/invalidate etc needed to perform.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

 

TinyPortal © 2005-2018