Recent

Author Topic: Exchanging items in TreeView  (Read 736 times)

maurobio

  • Full Member
  • ***
  • Posts: 142
Exchanging items in TreeView
« on: March 28, 2020, 03:15:06 pm »
Dear ALL,

The Items property of the ListView control has a handy Exchange() method which allows to programatically flip the position of an item with another.

My question is: is there any equivalent method in the TreeView control? I cound not find anything similar in the documentation of the Items property of TreeView. How to perform the equivalent of ListView.Items.Exchange() with TreeView.Items?

Thanks in advance for any assistance you can provide.

Best wishes,
UCSD Pascal / Burroughs 6700 / Master Control Program
Lazarus 1.9.3/2.0.4 - FPC 3.0.4 on GNU/Linux Mint 19 ("Tessa"), Windows XP SP3, Windows 7 Professional, Windows 10 Home

jamie

  • Hero Member
  • *****
  • Posts: 3096
Re: Exchanging items in TreeView
« Reply #1 on: March 28, 2020, 03:49:51 pm »
There is no exchange.. However, it can be done with multiple steps because I've done it...

Make a copy of the nodes that are going to get swapped so that you have the content info on them and then delete them and then reinsert them at the locations of interest..

 This goes to the widget level where OS is in control of all these handles etc..
The only true wisdom is knowing you know nothing

lucamar

  • Hero Member
  • *****
  • Posts: 2921
Re: Exchanging items in TreeView
« Reply #2 on: March 28, 2020, 04:16:07 pm »
Sholdn't be too difficult; something along the lines of this (untested) code:

Code: Pascal  [Select][+][-]
  1. type
  2.   { interposed TreeView class}
  3.   TTTreeView = class(ComCtrls.TTreeView)
  4.     procedure Exchange(const AIndex1: Integer; const AIndex2: Integer);
  5.   end;
  6.  
  7. { Implemented as ... }
  8. procedure TTreeView.Exchange(const AIndex1: Integer; const AIndex2: Integer);
  9. var
  10.   tmp: TTreeNode;
  11. begin
  12.   tmp := TTreeNode.Create(Items);
  13.   try
  14.     tmp.Asssign(Items[AIndex1]);
  15.     Items[AIndex1].Assign(Items[AIndex2]);
  16.     Items[AIndex2].Assign(tmp);
  17.   finally
  18.     tmp.FreeAllNodeData;
  19.     tmp.Free; {Not sure if this is needed...}
  20.   end;
  21. end;

You'll probably have to experiment a little to harden it properly, but the basic idea should work.
« Last Edit: March 28, 2020, 04:17:53 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

maurobio

  • Full Member
  • ***
  • Posts: 142
Re: Exchanging items in TreeView
« Reply #3 on: March 28, 2020, 08:04:55 pm »
@lucamar,

Thanks a lot a lot for the always helpful hints and code fragment. I'll test it ASAP and post the results. As far as I can see, it should work fine.

Best wishes,
UCSD Pascal / Burroughs 6700 / Master Control Program
Lazarus 1.9.3/2.0.4 - FPC 3.0.4 on GNU/Linux Mint 19 ("Tessa"), Windows XP SP3, Windows 7 Professional, Windows 10 Home

maurobio

  • Full Member
  • ***
  • Posts: 142
Re: Exchanging items in TreeView
« Reply #4 on: March 29, 2020, 03:39:44 pm »
Hi, @lucamar!

While I have not yet tested the code fragment you kindly provided, it just occurred to me that TTreeNode has a MoveTo method which could perform what I need. This method seems to be widely used along with drag and drop (for example, https://wiki.freepascal.org/Drag_and_Drop_sample). In fact, what I want is to provide the equivalent functionality of dragging and dropping of nodes inside the TreeView control, but using menu options (or command buttons) , instead of drag-and-drop.

Any hints?

Best wishes,

UCSD Pascal / Burroughs 6700 / Master Control Program
Lazarus 1.9.3/2.0.4 - FPC 3.0.4 on GNU/Linux Mint 19 ("Tessa"), Windows XP SP3, Windows 7 Professional, Windows 10 Home

jamie

  • Hero Member
  • *****
  • Posts: 3096
Re: Exchanging items in TreeView
« Reply #5 on: March 29, 2020, 04:20:24 pm »
That looks exactly what you need.

I have not tried that but it does look to be what you are looking for.
The only true wisdom is knowing you know nothing

maurobio

  • Full Member
  • ***
  • Posts: 142
Re: Exchanging items in TreeView
« Reply #6 on: March 29, 2020, 04:54:10 pm »
Thanks, @jamie.

But I do not use drag-&-drop, I prefer instead to provide menu options or command buttons for moving the nodes up and down. I would appreciate an working example of how to implement this (not the menus, of course, but just the appropriate events to move the nodes).

Best wishes,
UCSD Pascal / Burroughs 6700 / Master Control Program
Lazarus 1.9.3/2.0.4 - FPC 3.0.4 on GNU/Linux Mint 19 ("Tessa"), Windows XP SP3, Windows 7 Professional, Windows 10 Home

howardpc

  • Hero Member
  • *****
  • Posts: 3448
Re: Exchanging items in TreeView
« Reply #7 on: March 29, 2020, 05:55:51 pm »
Try this, an example for a move up.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.MoveUpButtonClick(Sender: TObject);
  2. var
  3.   SelectedNode: TTreeNode;
  4. begin
  5.   SelectedNode := TreeView1.Selected;
  6.   if (SelectedNode = Nil) or (SelectedNode.GetPrevSibling = Nil) then
  7.     Exit;
  8.   SelectedNode.MoveTo(SelectedNode.GetPrevSibling, naInsert);
  9.   SelectedNode.MakeVisible;
  10. end;

maurobio

  • Full Member
  • ***
  • Posts: 142
Re: Exchanging items in TreeView
« Reply #8 on: March 29, 2020, 11:09:39 pm »
@howardpc,

Thanks for the code fragment, which looks quite understandable and hopefully uesful.

Am I correct in supposing that for a move down I should use SelectedNode.MoveTo(SelectedNode.GetNextSibling, naInsert)?

Thanks for the help!

Best wishes,

UCSD Pascal / Burroughs 6700 / Master Control Program
Lazarus 1.9.3/2.0.4 - FPC 3.0.4 on GNU/Linux Mint 19 ("Tessa"), Windows XP SP3, Windows 7 Professional, Windows 10 Home

maurobio

  • Full Member
  • ***
  • Posts: 142
Re: Exchanging items in TreeView
« Reply #9 on: March 29, 2020, 11:46:30 pm »
Hi, @howardpc,

Your code fragment worked fine. However, I have not yet understand how to implement the move down option; using SelectedNode.MoveTo(SelectedNode.GetNextSibling, naInsert) has no effect, and using SelectedNode.MoveTo(SelectedNode.GetNextSibling, naAdd) moves the selected node to the end of the tree.

I attach a sample working project for your perusal.

Any hints?

Best wishes,
UCSD Pascal / Burroughs 6700 / Master Control Program
Lazarus 1.9.3/2.0.4 - FPC 3.0.4 on GNU/Linux Mint 19 ("Tessa"), Windows XP SP3, Windows 7 Professional, Windows 10 Home

howardpc

  • Hero Member
  • *****
  • Posts: 3448
Re: Exchanging items in TreeView
« Reply #10 on: March 30, 2020, 01:04:35 am »
Yes, it is tricky!
I don't think you need the MakeVisible call I inserted earlier, so you can remove that.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.MoveDownButtonClick(Sender: TObject);var
  2.   SelectedNode: TTreeNode;
  3. begin
  4.   SelectedNode := TreeView1.Selected;
  5.   if (SelectedNode = Nil) or (SelectedNode.GetNextSibling = Nil) then
  6.     Exit;
  7.   if SelectedNode.GetNextSibling.GetNextSibling <> Nil then
  8.     SelectedNode.MoveTo(SelectedNode.GetNextSibling.GetNextSibling, naInsert)
  9.   else
  10.     SelectedNode.MoveTo(SelectedNode.GetNextSibling, naAdd);
  11. end;
« Last Edit: March 30, 2020, 01:06:40 am by howardpc »

maurobio

  • Full Member
  • ***
  • Posts: 142
Re: Exchanging items in TreeView
« Reply #11 on: March 30, 2020, 01:20:04 am »
@howardpc,

Yes, it now works fine, for both the up and down events!

The updated sample code is attached.

I have still another question, but I will have to elaborate it better and modify the sample code. I will do this later.

Thanks for your help!

Best wishes
UCSD Pascal / Burroughs 6700 / Master Control Program
Lazarus 1.9.3/2.0.4 - FPC 3.0.4 on GNU/Linux Mint 19 ("Tessa"), Windows XP SP3, Windows 7 Professional, Windows 10 Home

 

TinyPortal © 2005-2018