delphi drag-and-drop virtualtreeview

delphi - VirtualTreeview arrastrar y soltar para organizar los nodos en una lista



drag-and-drop (2)

Si obtienes datos a través de GetNodeData, entonces tu drag and drop podría implementarse así:

uses ActiveX;

Asigna eventos de arrastre al árbol:

OnDragAllowed :

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

OnDragOver :

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

OnDragDrop :

procedure TForm1.vt1DragDrop(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode); var pSource, pTarget: PVirtualNode; attMode: TVTNodeAttachMode; begin pSource := TVirtualStringTree(Source).FocusedNode; pTarget := Sender.DropTargetNode; case Mode of dmNowhere: attMode := amNoWhere; dmAbove: attMode := amInsertBefore; dmOnNode, dmBelow: attMode := amInsertAfter; end; Sender.MoveTo(pSource, pTarget, attMode, False); end;

Además, no olvide configurar a toAutoDeleteMoveNodes en False en TreeOptions.AutoOptions .

Tengo una lista de nodos. Me gustaría agregar una función de arrastrar y soltar para reorganizar, pero no sé cómo hacer esto.

Intenté usar el evento OnDragDrop de TVirtualStringTree, pero no pude resolverlo. Miré la documentación y lamentablemente no hay un código de muestra mínimo allí para arrastrar y soltar nodo normal.

Tenga en cuenta que es solo una lista de un solo nivel. Sin jerarquía. :)


Varios nodos arrastrar y soltar:

procedure TForm1.vst(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode); var pSource, pTarget: PVirtualNode; attMode: TVTNodeAttachMode; List: TList<PVirtualNode>; begin pTarget := Sender.DropTargetNode; case Sender.GetNodeLevel(pTarget) of 0: case Mode of dmNowhere: attMode := amNoWhere; else attMode := amAddChildLast; end; 1: case Mode of dmNowhere: attMode := amNoWhere; dmAbove: attMode := amInsertBefore; dmOnNode, dmBelow: attMode := amInsertAfter; end; end; List:= TList<PVirtualNode>.create(); pSource := Sender.GetFirstSelected(); while Assigned(pSource) do begin List.Add(pSource); pSource := Sender.GetNextSelected(pSource); end; for pSource in List do Sender.MoveTo(pSource, pTarget, attMode, False); List.Free; end;