Skip to content

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.

treelist-nodedragdrop

When you drag nodes, node previews are shown. However, if you enable platform-based node drag-and-drop (required for dragging nodes between applications), node previews are not available.

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.

Enable Node Drag-and-Drop Between Applications

To allow nodes to be dragged between applications, enable the UsePlatformRowDragDrop property for the control that is the source of drag-and-drop operations.

Tip

The UsePlatformRowDragDrop property enables a drag-and-drop mode in which operations are handled by the Avalonia platform. No node previews are shown during platform-based drag operations.

Node Drag Mode - Start Drag Operations in Cells or Use Special Drag Handles

Tree List supports two node drag-and-drop modes that differ in how drag-and-drop operations are initiated. You can select the required mode using the control's RowDragMode property.

  • RowDragMode.Row mode (default) — Users can initiate a drag-and-drop operation in any node cell.

    grid-dragdrop-node

    In this mode, the default cell editor activation behavior is as follows:

    1. A user needs to focus a cell first.

    2. A click within the focused cell then activates a cell editor.

    To activate a cell editor on a single click, enable cell editor activation on mouse button release. Set the control's DataControlBase.EditorShowMode property to EditorShowMode.PointerReleased.

  • RowDragMode.DragHandle mode (new starting with v1.4) — Users can initiate a drag-and-drop operation by dragging a special drag handle. Drag handles are displayed in the Row Indicator region, which automatically appears to the left of the nodes when you activate RowDragMode.DragHandle mode.

    grid-dragdrop-drag-handle

    In DragHandle mode, cell editors are activated on a single press within a cell, by default. You can use the control's DataControlBase.EditorShowMode property to change this behavior.

    When multiple node selection is enabled, drag handles are shown for each selected node.

Related API:

  • RowIndicatorWidth — Specifies the width of the Row Indicator region, which displays drag handles.

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 the DragDropData 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 to DragDropEffects.None to cancel the current drag-and-drop operation. The drag-and-drop effect also determines the mouse pointer icon.
  • e.Nodes — An array of TreeListNode 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 the DragOver event.

  • e.Data — Specifies the DragDropData object that contains the data of the current drag-and-drop operation.
  • e.Effects — Specifies the drag-and-drop effect. Set this parameter to DragDropEffects.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 the TreeListControlBase.DragOver event.

    To cancel a drop operation in specific cases, handle the Drop event and set its e.Handled parameter to true.

    If a node is dropped outside the current TreeList/TreeView control, the Drop event does not fire for this control. See the TreeListControlBase.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 the TreeListControlBase.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 a Drop 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.

treelist-nodedragdrop-visualposition

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 its e.Effects event parameter to Avalonia.Input.DragDropEffects.None.

  • Handle the source control's TreeListControlBase.CompleteDragDrop event, and set the e.Handled event parameter to true.

    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.