Recent

Author Topic: How do I Drag/Drop from TTreeView to TTreeView  (Read 179 times)

guest48180

  • Guest
How do I Drag/Drop from TTreeView to TTreeView
« on: September 11, 2019, 12:45:47 am »
I try hard to stay out of the Forum's eyes due to the fact that I'm the least of all of you when it comes to coding. I'd rather drink turpentine and whiz on a brush fire as ask for help. But, pride aside, I need help with this.

This tutorial took me where I thought I needed to go, but then my code unraveled when I executed it. Unlike the tutorial, I'm not dragging text from a TEdit (not sure what real-world purpose this wld embody) to a TTreeView. Instead, I'm dragging nodes from one TTreeView to another TTreeView. And that's where it all falls apart.

I have two TTreeViews, one for Favorites and another for Main. My code for the Favorites TTreeView is:
Code: Pascal  [Select]
  1. procedure TForm_Main.TreeView_FavoritesMouseDown(Sender: TObject;
  2.   Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
  3. begin
  4.   if Button = mbLeft then
  5.     TreeView_Favorites.BeginDrag(True);
  6. end;  
  7.  
  8. procedure TForm_Main.TreeView_FavoritesDragOver(Sender,Source: TObject; X,
  9.   Y: Integer; State: TDragState; var Accept: Boolean);
  10. begin
  11.   Accept:= True;
  12. end;
  13.  
  14. procedure TForm_Main.TreeView_FavoritesDragDrop(Sender,Source: TObject; X,
  15.   Y: Integer);
  16. var
  17.   tv    : TTreeView;
  18.   iNode : TTreeNode;
  19. begin
  20.   tv:= TTreeView(Sender);
  21.   iNode:= tv.GetNodeAt(x,y);
  22.  
  23.   if Source is TTreeView then
  24.     tv.Items.AddChild(iNode, TTreeView(Source).Caption)
  25.   else if Source = Sender then
  26.      begin
  27.       if Assigned(tv.Selected) and
  28.         (iNode <> tv.Selected) then
  29.       begin
  30.         if iNode <> nil then
  31.           tv.Selected.MoveTo(iNode, naAddChild)
  32.         else
  33.           tv.Selected.MoveTo(iNode, naAdd);
  34.       end;
  35.      end;
  36. end;

And the Main TTreeView:
Code: Pascal  [Select]
  1. procedure TForm_Main.TreeView_MainMouseDown(Sender: TObject;
  2.   Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
  3. begin
  4.   if Button = mbLeft then
  5.     TreeView_Main.BeginDrag(True);
  6. end;
  7.  
  8. procedure TForm_Main.TreeView_MainDragOver(Sender,Source: TObject; X,
  9.   Y: Integer; State: TDragState; var Accept: Boolean);
  10. begin
  11.   Accept:= True;
  12. end;  
  13.  
  14. procedure TForm_Main.TreeView_MainDragDrop(Sender,Source: TObject; X,Y: Integer
  15.   );
  16. var
  17.   tv    : TTreeView;
  18.   iNode : TTreeNode;
  19. begin
  20.   tv:= TTreeView(Sender);
  21.   iNode:= tv.GetNodeAt(x,y);
  22.  
  23.   if Source is TTreeView then
  24.     tv.Items.AddChild(iNode, TTreeView(Source).Caption)
  25.   else if Source = Sender then
  26.      begin
  27.       if Assigned(tv.Selected) and
  28.         (iNode <> tv.Selected) then
  29.       begin
  30.         if iNode <> nil then
  31.           tv.Selected.MoveTo(iNode, naAddChild)
  32.         else
  33.           tv.Selected.MoveTo(iNode, naAdd);
  34.       end;
  35.   end;
  36. end;  

Because they're both TTreeViews, I think that's where the wires get crossed. What's happening is when I drag a node from the TreeView_Main to the TreeView_Favorites, the node stays in main, and a line is drawn (or an arrow added, depending on where I drop it) with no text. The node's text stays in TreeView_Main. I honestly believe line 23 is where the confusion begins...because both are TTreeViews. But I don't know. In the two pics provided, before and after shots, you can see the line drawn for the node "Yadda" with no text for it. But that's the only change made. Both TTreeViews' DragModes are set to dmAutomatic.

I don't need anyone to code it for me. Just tell me what I'm doing wrong. Send me a link or a good book title.

jamie

  • Hero Member
  • *****
  • Posts: 1990
Re: How do I Drag/Drop from TTreeView to TTreeView
« Reply #1 on: September 11, 2019, 01:25:08 am »
The sender is the control that is handling this event, in this case it would be the destination dropped on control.

 It may seem strange to be notified of this since this event was created just for the same control but this sender can be used in the event where another control decides to call some one else event instead of their own. In This case the SENDER would be the control it got dropped on but not the control that originally created the event, basically you can create a single event for many controls..

 The SOURCE in this case is the CONTROL that started the drag.

 so it looks like you are doing things backwards. The focused node is that of the SOURCE
and the TTreeView(Source).SelectedNode is what you need I guess.

P.S.
  YOu need to make a copy reference from it and create a new one for the dropped control.

  When done, you need to delete the one from the source I guess, if that is what you want to do.

Code: Pascal  [Select]
  1. procedure TForm1.ListView2DragDrop(Sender, Source: TObject; X, Y: Integer);
  2. var
  3.   N,NN:TListItem;
  4. begin
  5.   N := TListView(Source).ItemFocused;
  6.   NN := TListView(Sender).Items.Add;
  7.   NN.Assign(N);                          
  8.  

Something like that, you can elect to remove the IListItem from the source if you wish.


P.S.
 I made a mistake, wrong control Sorry, but you get the idea.

 Use the Node at..... to get the node/

« Last Edit: September 11, 2019, 01:44:26 am by jamie »

guest48180

  • Guest
Re: How do I Drag/Drop from TTreeView to TTreeView
« Reply #2 on: September 11, 2019, 03:32:46 am »
Thank you, jamie. I appreciate you taking your time to set me straight. I have more than enough to work with now. And that'll make baby sis happy...until she throws something else at me that I can't do :D