Edit this page

Drag and Drop

The Telerik RadTreeView control enhances further your application's capabilities through the rich drag-and-drop functionality. Your users can create and re-order any hierarchical structures and easily perform various drag-and-drop operations.

This tutorial will walk you through the following common tasks:

With the Q2 2013 release we extended the RadTreeView DragDrop built-in implementation to also use the DragDropManager. For the moment the old RadDragAndDropManager logic will be kept but you need to set the TreeViewSettings.DragDropExecutionMode property to Legacy in order to enable it. However, it is important to note that we will remove this Legacy DragDropExecutionMode as soon as the RadDragAndDropManager is removed.

For the purposes of this tutorial will be used the following treeview declaration:

XAML

<telerik:RadTreeView x:Name="radTreeView" IsDragDropEnabled="True">
    <telerik:RadTreeViewItem Header="Sport Categories">
        <telerik:RadTreeViewItem Header="Football">
            <telerik:RadTreeViewItem Header="Futsal"/>
            <telerik:RadTreeViewItem Header="Soccer"/>
        </telerik:RadTreeViewItem>
        <telerik:RadTreeViewItem Header="Tennis">
            <telerik:RadTreeViewItem Header="Table Tennis"/>
        </telerik:RadTreeViewItem>
        <telerik:RadTreeViewItem Header="Cycling">
            <telerik:RadTreeViewItem Header="Road Cycling"/>
            <telerik:RadTreeViewItem Header="Indoor Cycling"/>
            <telerik:RadTreeViewItem Header="Mountain Bike"/>
        </telerik:RadTreeViewItem>
    </telerik:RadTreeViewItem>
</telerik:RadTreeView>

Enable Drag and Drop

To allow drag and drop functionality in RadTreeView, set the IsDragDropEnabled attribute to True. Find your treeview declaration and add the following attribute:

XAML

<telerik:RadTreeView x:Name="radTreeView" IsDragDropEnabled="True" >

The drag and drop behavior can be enabled in the code-behind. In order to do that you need to set the IsDragDropEnabled property of an instance of the RadTreeView class to True.

C#

  private void EnableDragAndDrop()
        {
            radTreeView.IsDragDropEnabled = true;
        }

VB.NET

Private Sub EnableDragAndDrop()
    radTreeView.IsDragDropEnabled = True
End Sub

If the treeview is bound, it is best to be bound to an ObservableCollection. Otherwise the result of the drag and drop will not be visible. Also the ItemsSource collection of the items to which the leaves nodes of the treeview are bound, need to be initialized as well, otherwise drops in them will not be possible.

If the ItemSource of the RadTreeView (RadTreeViewItem) is not an IList, then the drop operation is not allowed.

Visual Elements of the Drag and Drop Operation

Once enabled, dragging behavior by default allows items to be dropped on other items and between items. A line between the Items will be displayed briefly as a visual indicator that the node can be dropped in the location of the line. See the next figure.
Rad Tree View-Drag Drop-Preview Line

The Drag and Drop operation contains three visual elements (tooltips):

  • Drag Preview
  • Drag Tooltip
  • Drop Preview Line

Rad Tree View-Drag Drop-Visual Elements

More details about how to disable each one of the elements you will find later in the topic.

Enable Drag of Multiple Items

To allow multiple items to be dragged at one time, you need to set the SelectionMode attribute of the treeview to Multiple or Extended. Add the following attribute to your treeview declaration:

XAML

<telerik:RadTreeView x:Name="radTreeView" 
                     IsDragDropEnabled="True" 
                     SelectionMode="Multiple">

Dragging multiple nodes at once can be enabled in the code-behind. In order to do so, you need to set the SelectionMode property of an instance of the RadTreeView class to Multiple or Extended.

C#

private void EnableDragOfMultipleNodes()
{
    radTreeView.SelectionMode = Telerik.Windows.Controls.SelectionMode.Multiple;
}

VB.NET

Private Sub EnableDragOfMultipleNodes()
    radTreeView.SelectionMode = Telerik.Windows.Controls.SelectionMode.Multiple
End Sub

Here is the result:
Rad Tree View-Drag Drop-Multiple Drag

Disable Drop Operation on Specific Item

You can further tailor the drag and drop behavior per Node by setting the boolean RadTreeViewItem property IsDropAllowed.

For example, if you want to disable the drop on the treeview item with Header "Tennis", add the following attribute to the treeview item declaration:

XAML

<telerik:RadTreeViewItem Header="Tennis" x:Name="radTreeViewItemTennis" IsDropAllowed="False">

In order to disable drop operation on specific item you should set the IsDropAllowed property of an instance of the RadTreeViewItem class to False.

C#

private void DisableDropOnSpecificItem()
{
    radTreeViewItemTennis.IsDropAllowed = false;
}

VB.NET

Private Sub DisableDropOnSpecificItem()
    radTreeViewItemTennis.IsDropAllowed = False
End Sub

Here is the result:
Rad Tree View-Drag Drop-Disable Drop

By default each visual element (drag preview, drop preview line, drag tooltip) of the drag and drop operation is enabled. In the next several sections you will see how to disable each one of them.

Disable Drag Preview

In order to disable the Drag Preview you need to set the IsDragPreviewEnabled attribute of the treeview to False. Find your treeview declaration and add the following attribute:

XAML

<telerik:RadTreeView x:Name="radTreeView" IsDragDropEnabled="True" IsDragPreviewEnabled="False">

The same operation can be done in the code-behind. In order to do that you need to set the IsDragPreviewEnabled property of an instance of the RadTreeView class to False.

C#

private void DisableDragPreview()
{
    radTreeView.IsDragPreviewEnabled = false;
}

VB.NET

Private Sub DisableDragPreview()
    radTreeView.IsDragPreviewEnabled = False
End Sub

Here is the result. When you drag treeview items, the drag preview element is no longer visible.

Disable Drag Tooltip

In order to disable the Drag Tooltip you need to set the IsDragTooltipEnabled attribute of the treeview to False. Find your treeview declaration and add the following attribute:

XAML

<telerik:RadTreeView x:Name="radTreeView" IsDragDropEnabled="True"
    IsDragPreviewEnabled="False"
    IsDragTooltipEnabled="False">

The same operation can be done in the code-behind. In order to do that you need to set the IsDragTooltipEnabled property of an instance of the RadTreeView class to False.

C#

private void DisableDragTooltip()
{
    radTreeView.IsDragTooltipEnabled = false;
}

VB.NET

Private Sub DisableDragTooltip()
    radTreeView.IsDragTooltipEnabled = False
End Sub

Here is the result. When you drag treeview items, the drag preview and drag tooltip elements are no longer visible.

Disable Drop Preview Line

In order to disable the last visual element - the Drag Preview Line you need to set the IsDropPreviewLineEnabled attribute of the treeview to False. Find your treeview declaration and add the following attribute:

XAML

<telerik:RadTreeView x:Name="radTreeView" 
                    IsDragDropEnabled="True"
                    IsDragPreviewEnabled="False"
                    IsDragTooltipEnabled="False"
                    IsDropPreviewLineEnabled="False">

The same operation can be done in the code-behind. In order to do that you need to set the IsDropPreviewLineEnabled property of an instance of the RadTreeView class to False.

C#

private void DisableDropPreviewLine()
{
    radTreeView.IsDropPreviewLineEnabled = false;
}

VB.NET

Private Sub DisableDropPreviewLine()
    radTreeView.IsDropPreviewLineEnabled = False
End Sub

Here is the result. When you drag treeview items, all visual elements are disabled (hidden).

RadDragAndDropManager Events

Please note that these events are only available with the Legacy DragDropExecutionMode which will be removed. This is why we highly recommend that you use the DragDropExecutionMode.New which since Q2 2014 is the default setting. Its events are described in the Using DragDropManager events to manage the drag and drop process section.

The RadTreeView API offers you four events for managing the drag and drop behavior:

  • PreviewDragStarted
  • DragStarted
  • PreviewDragEnded
  • DragEnded

XAML

<telerik:RadTreeView x:Name="radTreeView" IsDragDropEnabled="True"
    PreviewDragStarted="radTreeView_PreviewDragStarted"
    DragStarted="radTreeView_DragStarted"
    PreviewDragEnded="radTreeView_PreviewDragEnded"
    DragEnded="radTreeView_DragEnded">

The RadTreeView actually uses and handles the DragDrop events of the RadDragAndDropManager. In fact, they can be used for managing the drag and drop process, too. You should use the AddHandler() method of the treeview.

public void AddHandler( RoutedEvent routedEvent, Delegate handler, bool handledEventsToo );

When RadTreeView detects a valid drag operation, it generates a PreviewDragStarted and DragStarted routed events. When a valid drop operation (the selected Item is dropped onto another Item or in between Items) is detected, a PreviewDragEnded and DragEnded events are generated. Both PreviewDragStarted and PreviewDragEnded events can be cancelled by setting the Handled property of the event argument to True in the event handler.

C#

private void radTreeView_PreviewDragEnded( object sender, RadTreeViewDragEndedEventArgs e )
{
    e.Handled = true;
}

VB.NET

Private Sub radTreeView_PreviewDragEnded(ByVal sender As Object, ByVal e As RadTreeViewDragEndedEventArgs)
    e.Handled = True
End Sub

Handling the PreviewDragStarted event will cancel the drag operation. This is equivalent to set the RadTreeView's IsDragDropEnabled property to False. 'e.Handled = True' - where 'e' is the RadTreeViewDragEventArgs class passed as an argument of the event handler.

Handling the PreviewDragEnded event will cancel the drop operation. This is useful, when you want to cancel adding/removing items from the RadTreeView's ItemsCollection. 'e.Handled = True' - where 'e' is the RadTreeViewDragEventArgs class passed as an argument of the event handler.

The type of the event arguments for the PreviewDragStarted and DragStarted events is RadTreeViewDragEventArgs. Via the RadTreeViewDragEventArgs you can get access to the items being dragged:

C#

private void radTreeView_DragStarted( object sender, RadTreeViewDragEventArgs e )
{
    Collection<Object> draggedItems = e.DraggedItems;
}

VB.NET

Private Sub radTreeView_DragStarted(ByVal sender As Object, ByVal e As RadTreeViewDragEventArgs)
    Dim draggedItems As Collection(Of [Object]) = e.DraggedItems
End Sub

The type of the event arguments for the PreviewDragEnded and DragEnded events is RadTreeViewDragEndedEventArgs. Via the RadTreeViewDragEndedEventArgs you can get access to the following items and properties:

  • DraggedItems- a collection of Items being dragged (this is useful when multi-selection is enabled - SelectionMode property of the RadTreeView is set to True).
  • DropPosition- indicates the relationship of the Items being dropped and can be a DropPosition enumeration value After, Below or Inside.
  • TargetDropItem- the Item being dragged to.
  • IsCanceled- boolean property, indicates whether the drag and drop operation is cancelled or not.

C#

private void radTreeView_DragEnded( object sender, RadTreeViewDragEndedEventArgs e )
{
    // Get the dragged items.
    Collection<Object> draggedItems = e.DraggedItems;
    // Get the drop position.
    DropPosition dropPosition = e.DropPosition;
    switch ( dropPosition )
    {
        case DropPosition.After:
            MessageBox.Show( "After" );
            break;
        case DropPosition.Before:
            MessageBox.Show( "Before" );
            break;
        case DropPosition.Inside:
            MessageBox.Show( "Inside" );
            break;
    }
    // Get is canceled
    bool isCanceled = e.IsCanceled;
    // Target drop item
    RadTreeViewItem targetDropItem = e.TargetDropItem;
    if ( targetDropItem.Header.ToString() == "Tennis" )
    {
        // Do something
    }
}

VB.NET

Private Sub radTreeView_DragEnded(ByVal sender As Object, ByVal e As RadTreeViewDragEndedEventArgs)
    ' Get the dragged items. '
    Dim draggedItems As Collection(Of [Object]) = e.DraggedItems

    ' Get the drop position. '
    Dim dropPosition__1 As DropPosition = e.DropPosition
    Select Case dropPosition__1
        Case DropPosition.After
            MessageBox.Show("After")
            Exit Select
        Case DropPosition.Before
            MessageBox.Show("Before")
            Exit Select
        Case DropPosition.Inside
            MessageBox.Show("Inside")
            Exit Select
    End Select

    ' Get is canceled '
    Dim isCanceled As Boolean = e.IsCanceled

    ' Target drop item '
    Dim targetDropItem As RadTreeViewItem = e.TargetDropItem
    If targetDropItem.Header.ToString() = "Tennis" Then
        ' Do something '
    End If
End Sub

Note that the TargetDropItem property may be null if the drop is in an empty treeview. That's why when you use that property it always has to be checked:

private void radTreeView_DragEnded(object sender, RadTreeViewDragEndedEventArgs e)
{
  // Target drop item
  RadTreeViewItem targetDropItem = e.TargetDropItem;
  if (targetDropItem != null && targetDropItem.Header.ToString() == "Tennis" )
  {
    // Do something
  }
}       

Using DragDropManager events to manage the drag and drop process

With Q2 2012 you can use the DragDropManager events to customize the new DragDrop logic of RadTreeView.

RadTreeView internally handles the following DragDropManager events:

  • DragInitialize - The DragInitialize event occurs when an object is about to be dragged. Therefore the RadTreeView handles it internally to set all needed information regarding the drag - the DraggedItems, the DragVisual and the settings of the operation. This information is wrapped in a TreeViewDragDropOptions object and passed to the arguments of the event.

  • GiveFeedback - This event is continuously fired by the drag source during a drag-and-drop operation. Therefore the RadTreeView handles it internally to apply an Arrow cursor during the drag operation.

  • DragOver - This event occurs continuously while an object is dragged (moved) within the drop target's boundary. Therefore the RadTreeView handles it internally to update the DropPreview Line position as well as the current action and position of the drop.
  • DragLeave - This event occurs when an object is dragged out of the drop target's boundary. Therefore the RadTreeView handles it internally to update the DropPreview Line position as well as the current action and position of the drop.
  • Drop - This event occurs when an object is dropped on the drop target. Therefore the RadTreeView handles it internally to implement the drop operation.
  • DragDropCompleted - This event occurs when an object is dropped on the drop target and is used to notify the source that the drag operation is over. Therefore the RadTreeView handles it internally to update its state and items based on the DropAction type of a successful drop. As RadTreeView handles internally the above DragDropManager events, in order to invoke a custom handler, you need to explicitly specify that you're adding a handler that should be invoked even for already handled events. This is done through the last - bool argument of the DragDropManager.Add[Event]Handler extension method.

C

DragDropManager.AddDragOverHandler(xTreeView, OnDragOver,true);  

VB.NET

DragDropManager.AddDragOverHandler(xTreeView, OnDragOver, True) 

You can find more information about the DragDropManager events in the Events tutorial.

Using the TreeViewDragDropOptions object

When a drag operation starts, RadTreeView creates an object of type TreeViewDragDropOptions and passes it as the Data of the drag. You can extract that object through the event arguments of the DragDropManager events.

C#

private void DisableDragPreview()
{
    radTreeView.IsDragPreviewEnabled = false;
}

VB.NET

Private Sub DisableDragPreview()
    radTreeView.IsDragPreviewEnabled = False
End Sub

The TreeViewDragDropOptions class exposes the following properties:

  • DropAction - Gets or sets the drop action that should be executed when drag drop operation completes. It is an enumeration of type DropAction that exposes the following members:

    • Copy - dragged items will be added to the destination and will not be removed from the source.
    • Move - dragged items will be added to the destination and will be removed from the source.
    • Delete - dragged items will not be added to the destination and will be removed from the source.
    • None - dragged items will not be added to the destination and will not be removed from the source. If the drop operation is allowed, the default DropAction is Move. And in order to change this logic, it would be best to define a custom DragOverHandler and customize the DropAction value in it. However, please note that you need to handle the DragDropManager DragOver event of the RadTreeView that is acting as a destination for the drop operation.

    C#

    private void EnableDragAndDrop()
    {
        radTreeView.IsDragDropEnabled = true;
        TreeViewSettings.SetDragDropExecutionMode(radTreeView, TreeViewDragDropExecutionMode.New);
         DragDropManager.AddDragOverHandler(radTreeView2, OnTreeItemDragOver, true);
    }
    
    private void OnTreeItemDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
    {
        var options = DragDropPayloadManager.GetDataFromObject(e.Data, TreeViewDragDropOptions.Key) as TreeViewDragDropOptions;
        options.DropAction = DropAction.Copy;
    }
    

    VB.NET

    Private Sub EnableDragAndDrop()
        radTreeView.IsDragDropEnabled = True
    End Sub
    
  • DropPosition - Gets or sets the drop position of the dragged items. It is an enumeration of type DropPosition that provides the following members:

    • Before - indicates that the dragged items will be dropped before the target.
    • Inside - indicates that the dragged items will be dropped inside the target.
    • After - indicates that the dragged items will be dropped after the target.
    • Undefined - indicates that the drop position of the item is not yet determined.
  • DragVisual - Gets or sets a visual representation of the drag/drop operation state. By default a TreeViewDragVisual object is created automatically.
  • DraggedItems - Gets an IEnumerable collection populated with the dragged items.
  • DragSourceItem - Gets the RadTreeViewItem which has started the current drag/drop operation. This property is initialized when the drag operation starts and it will be null if the RadTreeView control is not the source of the operation.
  • DropTargetItem - Gets the RadTreeViewItem laying under the drop point. This property is initialized while dragging directly over a RadTreeViewItem and it is set to null as soon as the drag leaves the bounds of the RadTreeViewItem.
  • DropTargetTree - Gets the RadTreeView laying under the drop point. This property is initialized while dragging directly over a RadTreeView and it is set to null as soon as the drag leaves the bounds of the RadTreeView. The TreeViewDragDropOptions exposes one method - UpdateDragVisual(). It should be used to update the DragVisual property value in case it is of type TreeViewDragVisual.

You need to call the TreeViewDragDropOptions UpdateDragVisual() method when the changes in the values of the TreeViewDragDropOptions members should be reflected in the DragVisual. For instance, if you need to disable a drag operation and you set the TreeViewDragDropOptions DropAction value to None, the visual feedback of the operation won't reflect that change although the drop operation will be forbidden. And in order to make the RadTreeView instance update its DragVisual to display a DropImpossible indicator, you need to invoke the UpdateDragVisual() method.

DragDrop AutoScrolling Behavior

With Q2 2013, if you use the New TreeViewSettings.DragDropExecutionMode, then you will be able to take advantage of the built-in auto-scrolling functionality implemented in RadTreeView. Moreover, there are a set pf properties exposed to allow you to customize the auto-scrolling functionality to better fit your needs.

The auto-scrolling functionality is controlled through the following attached properties:

  • ScrollingSettingsBehavior.IsEnabled - gets or sets a bool value indicating whether the auto-scrolling behavior is enabled.
  • ScrollingSettingsBehavior.ScrollStep - gets or sets a double value defining the scrolling offset used to define a single step during the scroll operation.
  • ScrollingSettingsBehavior.ScrollStepTime - gets or sets a TimeSpan value defining the timeout period between two scroll steps.

Drag and Drop Between TreeViews

The Telerik RadTreeView allows you to perform drag and drop between treeviews - this is a default behavior.

Let's define the sports categories RadTreeView twice in our view:

XAML

<Grid.ColumnDefinitions>
    <ColumnDefinition/>
    <ColumnDefinition/>
</Grid.ColumnDefinitions>
<telerik:RadTreeView x:Name="radTreeView1" IsDragDropEnabled="True">
    <telerik:RadTreeViewItem Header="Sport Categories">
        <telerik:RadTreeViewItem Header="Football">
            <telerik:RadTreeViewItem Header="Futsal"/>
            <telerik:RadTreeViewItem Header="Soccer"/>
        </telerik:RadTreeViewItem>
        <telerik:RadTreeViewItem Header="Tennis">
            <telerik:RadTreeViewItem Header="Table Tennis"/>
        </telerik:RadTreeViewItem>
        <telerik:RadTreeViewItem Header="Cycling">
            <telerik:RadTreeViewItem Header="Road Cycling"/>
            <telerik:RadTreeViewItem Header="Indoor Cycling"/>
            <telerik:RadTreeViewItem Header="Mountain Bike"/>
        </telerik:RadTreeViewItem>
    </telerik:RadTreeViewItem>
</telerik:RadTreeView>
<telerik:RadTreeView x:Name="radTreeView2" Grid.Column="1" IsDragDropEnabled="True">
    <telerik:RadTreeViewItem Header="Sport Categories">
        <telerik:RadTreeViewItem Header="Football">
            <telerik:RadTreeViewItem Header="Futsal"/>
            <telerik:RadTreeViewItem Header="Soccer"/>
        </telerik:RadTreeViewItem>
        <telerik:RadTreeViewItem Header="Tennis">
            <telerik:RadTreeViewItem Header="Table Tennis"/>
        </telerik:RadTreeViewItem>
        <telerik:RadTreeViewItem Header="Cycling">
            <telerik:RadTreeViewItem Header="Road Cycling"/>
            <telerik:RadTreeViewItem Header="Indoor Cycling"/>
            <telerik:RadTreeViewItem Header="Mountain Bike"/>
        </telerik:RadTreeViewItem>
    </telerik:RadTreeViewItem>
</telerik:RadTreeView>

Now you can drag and drop items from one treeview to another:
Rad Tree View-Drag Drop-Tree To Tree

Drag and Drop Between TreeView and Other Controls

You can use the built-in RadTreeView DragDrop when implementing drag-drop between the tree and other controls such as a ListBox. For more information you can read the topic How To Implement Drag and Drop Between TreeView and ListBox.

See Also