Bernard 18 Posted January 20, 2022 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
Stano 143 Posted January 20, 2022 (edited) 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 January 20, 2022 by Stano 1 Share this post Link to post
Stano 143 Posted January 20, 2022 You can also use the internal order numbering. Although not highly recommended. AbsoluteIndex. Share this post Link to post
Bernard 18 Posted January 20, 2022 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