Node Drag-and-Drop
TreeList and TreeView controls support the node drag-and-drop functionality within the controls and to external controls. The drag-and-drop feature is implemented in the base class of TreeList and TreeView, TreeListControlBase
. This class exposes the API to enable and handle node drag-and-drop operations.
Enable Node Drag-and-Drop
Set the TreeListControlBase.AllowDragDrop
property to true
to enable node drag-and-drop. In this case a user can drag a node within the TreeList/TreeView control and outside the control.
A drag-and-drop operation moves a node to another position, and also changes the position of a corresponding business object in the data source.
If a node is dragged to an external control, the default behavior of the TreeList/TreeView control is to remove the node from the current control, and delete the corresponding business object from the control's data source. See Node Drag-and-Drop Between Controls for information on how to prevent nodes and business objects from being deleted.
Drag-and-drop of multiple nodes is supported if you enable multiple node selection using the DataControlBase.SelectionMode
property (see Nodes - Multiple Node Selection (Highlight)).
TreeList and TreeView controls do not maintain automatic copy operations during drag-and-drop. Pressing the CTRL key is not in effect.
Drag-and-drop of Sorted Data
TreeList and TreeView nodes can be sorted. Node drag-and-drop operations within sorted TreeList and TreeView controls are disabled by default. Set the TreeListControlBase.AllowDragDropSortedNodes
property to true
to enable drag-and-drop operations within sorted controls.
If data is sorted and a node is dragged to a position before or after another node, the control automatically updates the dragged node's value(s) in the sorted column(s) to keep the current sort order. The dragged node's values in the sorted columns are set to corresponding values of the target node.
Handle Drag-and-Drop Operations with Events
The TreeList and TreeView controls contain events that help you manage and respond to node drag-and-drop operations.
Start Drag-and-Drop
The TreeListControlBase.StartDrag
event fires when a drag-and-drop operation is about to start. Use the following event parameters to get information about the current drag-and-drop operation.
e.Data
— Specifies theAvalonia.Input.IDataObject
object that contains the data of the current drag-and-drop operation.e.DragElement
— The visual element being dragged.
e.Effects
— Specifies the drag-and-drop effect. Set this parameter toDragDropEffects.None
to cancel the current drag-and-drop operation. The drag-and-drop effect also determines the mouse pointer icon.e.Nodes
— An array ofTreeListNode
objects that are about to be dragged. This array contains a single object if only one node is being dragged.
Example - Prevent a drag-and-drop operation from starting for specific nodes
The following StartDrag
event handler disables drag-and-drop operations for nodes that contain children.
private void TreeList_StartDrag(object sender, TreeListStartDragEventArgs e)
{
if(e.Nodes[0].HasChildren)
e.Effects = Avalonia.Input.DragDropEffects.None;
}
Handle the Drag Stage During Drag-and-Drop
The TreeListControlBase.DragOver
event is raised repeatedly while a user drags a node(s) over another node. The event's arguments allow you to identify information related to the current drag-and-drop operation:
e.DragNodes
— An array of treelist nodes (TreeListNode
) being dragged. This array contains a single object if only one node is being dragged.e.TargetNode
— The treelist node over which the node(s) is dragged.e.DropPosition
— Specifies the potential drop position relative to the target node. Available options include:DropPosition.Before
— The dragged node(s), if dropped, will be added at the same hierarchy level before the target node.DropPosition.After
— The dragged node(s), if dropped, will be added at the same hierarchy level after the target node.DropPosition.Inside
— The dragged node(s), if dropped, will be added as a child of the target node.
e.KeyModifiers
— Specifies whether the ALT, SHIFT and/or CTRL key is pressed during theDragOver
event.e.Data
— Specifies theAvalonia.Input.IDataObject
object that contains the data of the current drag-and-drop operation.e.Effects
— Specifies the drag-and-drop effect. Set this parameter toDragDropEffects.None
to cancel the current drag-and-drop operation. The drag-and-drop effect also determines the mouse pointer icon.
Example - Prevent nodes from being dropped at the root level
The following DragOver
event handler prevents nodes from being dropped next to root nodes. The code still allows nodes to be dropped as children of root nodes.
private void TreeList_DragOver(object sender, TreeListDragEventArgs e)
{
if(e.TargetNode?.Level == 0 && (e.DropPosition==DropPosition.Before || e.DropPosition == DropPosition.After))
e.Effects = Avalonia.Input.DragDropEffects.None;
}
Finish Drag-and-Drop
Two events are available to help you manage the drop stage of a drag-and-drop operation:
TreeListControlBase.Drop
— Fires when a node is about to be dropped over another treelist node. The event's arguments match those of theTreeListControlBase.DragOver
event.To cancel a drop operation in specific cases, handle the
Drop
event and set itse.Handled
parameter totrue
.If a node is dropped outside the current TreeList/TreeView control, the
Drop
event does not fire for this control. See theTreeListControlBase.CompleteDragDrop
event's description below for more information.Example — Modify a dropped node's values
The following
Drop
event handler changes a value of a dragged node(s) when it is dropped. It is assumed that the data source contains the "Assignee" field. The code below sets the dropped node's "Assignee" field to the target node's "Assignee" field value.private void TreeList_Drop(object sender, TreeListDragEventArgs e) { if (e.DropPosition != DropPosition.Inside) return; TreeListControl treeList = e.Source as TreeListControl; string newAssignee = treeList.GetCellValue(e.TargetNode, "Assignee").ToString(); foreach (TreeListNode node in e.DragNodes) { treeList.SetCellValue(node, "Assignee", newAssignee); } }
TreeListControlBase.CompleteDragDrop
— Fires after a drag-and-drop operation has been finished within the current control or outside the current control.The
TreeListControlBase.CompleteDragDrop
event fires after theTreeListControlBase.Drop
event.The following arguments are available for the
TreeListControlBase.CompleteDragDrop
event:e.DragNodes
— An array of treelist nodes (TreeListNode
) that have been dropped.e.Effects
— Returns the drag-and-drop effect that has been set in aDrop
event handler of the control on which the node has been dropped.
See also: Node Drag-and-Drop Between Controls
Drag-and-Drop Options
The TreeList/TreeView controls expose the following options to customize node drag-and-drop operations:
TreeListControlBase.AutoExpandOnDrag
— Gets or sets whether collapsed nodes are automatically expanded when hovered during a drag-and-drop operation.TreeListControlBase.AutoExpandDelayOnDrag
— Gets or sets the delay before collapsed nodes are automatically expanded when the mouse is over them during a drag-and-drop operation.TreeListControlBase.AllowScrollingOnDrag
— Gets or sets whether the TreeList/TreeView automatically scrolls nodes when you drag a node at the control's top or bottom edge.
Node Drag-and-Drop Between Controls
Drag-and-drop of nodes (rows) is automatically supported between TreeListControl
, TreeViewControl
and DataGridControl
controls. Use the AllowDragDrop
option exposed by these controls to enable the drag-and-drop functionality for them.
Visual Indication of Drag-and-Drop
When a node (row) is dragged, TreeListControl
, TreeViewControl
and DataGridControl
controls visually indicate a potential drop position.
Automatic Movement of a Node (Row) and Its Item from the Source to the Target Control
TreeListControl
, TreeViewControl
and DataGridControl
support automatic movement of a dragged node (row) between these controls during a drag-and-drop operation: a new node (row) containing dragged data is added to the target control, and the dragged node (row) is then removed from the source control. The corresponding item (business object) is transferred between the source and target controls' item sources, as well.
Automatic movement of a node (row) and the corresponding item occurs if the data type of items in the source control matches or compatible with the data type of items in the target control. See the Type.IsAssignableFrom
method, used to check the compatibility of data types.
To prevent a node (row) and item from being deleted in the source control during a drag-and-drop operation to external controls, you can do one of the following:
Handle the target control's
Drop
event and set itse.Effects
event parameter toAvalonia.Input.DragDropEffects.None
.Handle the source control's
TreeListControlBase.CompleteDragDrop
event, and set thee.Handled
event parameter totrue
.private void TreeList_CompleteDragDrop(object sender, TreeListCompleteDragDropEventArgs e) { e.Handled = true; }
Drag-and-Drop to Other Controls
The TreeListControl
, TreeViewControl
and DataGridControl
controls do not maintain automatic drag-and-drop of rows/nodes to other controls (for instance, the standard Avalonia DataGrid
). To allow nodes/rows to be dragged to these controls, enable the drag-and-drop functionality for them using the Avalonia.Input.DragDrop.AllowDrop
attached property. Handle the target control's Avalonia.Input.DragDrop.Drop
attached event to accept dragged nodes (rows). While handling the DragDrop.Drop
event, you can access the dragged nodes (rows) from the Data
event parameter.