Jump to content
Sign in to follow this  
Bernard

Virtual Treeview

Recommended Posts

I have been looking to find the best way to move rows in a VirtualTreeview and want to check that this is the best way

 

I put this code into the Minimal VT Demo

 

Depending on the drag direction I want to either move the row to position above or below the drop position.

 

It works but it requires setting up a global mouse position vtStartDragPoint.

 

Is there a more elegant way?

 

procedure TMainForm.VSTDragAllowed(Sender: TBaseVirtualTree; Node: PVirtualNode;  Column: TColumnIndex; var Allowed: Boolean);
begin
  Allowed := True;
end;

 

procedure TMainForm.VSTDragDrop(Sender: TBaseVirtualTree; Source: TObject;  DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState;  Pt: TPoint; var Effect: Integer; Mode: TDropMode);
var
  Nodes: TNodeArray;
  Attachmode: TVTNodeAttachMode;
begin
   Effect := DROPEFFECT_MOVE;
   var vtEndDragPoint := Mouse.CursorPos;
   if vtStartDragPoint.y < vtEndDragPoint.y then
     Attachmode:= amInsertAfter
   else
     Attachmode:= amInsertBefore;


   Nodes:= vst.GetSortedSelection(false);
   VST.MoveTo(Nodes[0], Sender.DropTargetNode, Attachmode, false);
end;

 

procedure TMainForm.VSTDragOver(Sender: TBaseVirtualTree; Source: TObject;  Shift: TShiftState; State: TDragState; Pt: TPoint; Mode: TDropMode;  var Effect: Integer; var Accept: Boolean);
begin
  Accept := True;
end;

 

procedure TMainForm.VSTStartDrag(Sender: TObject; var DragObject: TDragObject);
begin
  vtStartDragPoint :=  Mouse.CursorPos;
end;

Share this post


Link to post

I personally always use amInsertBefore. The user quickly finds out and arranges accordingly. Of course, the problem is when the row has to go to the end. Then he must move two rows.

    Sender.MoveTo(Sender.FocusedNode, Sender.DropTargetNode, amInsertBefore, False);

 

Edited by Stano
  • Like 1

Share this post


Link to post

You can also use the internal order numbering. Although not highly recommended. AbsoluteIndex.

Share this post


Link to post
22 minutes ago, Stano said:

I personally always use amInsertBefore. The user quickly finds out and arranges accordingly. Of course, the problem is when the row has to go to the end. Then he must move two rows.


    Sender.MoveTo(Sender.FocusedNode, Sender.DropTargetNode, amInsertBefore, False);

 

Yes this was the issue I was trying to fix and the above code sorts it by detecting the direction of the drag.

Share this post


Link to post

So use that AbsoluteIndex.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×