Drag and Drop management is implemented as a set of Behavior like attached dependency properties defined on the static class DevComponents.WPF.Controls.DragDrop. Setting up drag and drop is simple:

  • To set up an element to be the source of a drag operation, set attached property DragDrop.IsDragSource = true.
  • To set up an element to be the recipient of a drop operation, set attached property DragDrop.IsDropTarget = true.

A single element can be both drag source and drop target. (Which is how to enable moving items within a single ItemsControl, for example.)

  • Tip: To make an element a drop target only when it is also the drag source, set DragDrop.IsDropTarget=null or “{x:Null}” in Xaml.

Essentially any UIElement can be drag source or drop target using custom handlers. However, there is currently out-of-the-box support for the following:

  • AdvTree Control.
  • AdvGrid Control.
  • Many ItemsControl based Controls (TreeView is not supported.)

A drop operation can be set up to either copy the data or move the data by setting the attached property DragDrop.DropAction on the drop target appropriately.

Following is an example in Xaml of setting up an AdvTree control for drag drop. Notice the inclusion of a custom drag adorner template (described below):

<dc:AdvTree ItemsSource="{Binding Source={StaticResource FileSystem}, Path=Drives}"
            dc:DragDrop.IsDragSource="True" dc:DragDrop.IsDropTarget="True">
    <dc:DragDrop.DragAdornerTemplate>
        <DataTemplate>
            <Border Background="White" BorderBrush="Black" BorderThickness="1" Padding="5,1">
                <TextBlock Text="{Binding Name}" />
            </Border>
        </DataTemplate>
    </dc:DragDrop.DragAdornerTemplate>
</dc:AdvTree>

Custom Adorners

Two types of adorners can be displayed during a drag/drop operation. The first is an adorner which provides visual information about the data being transferred. This is called a DragAdorner. The second is the adorner which provides visual information about the location of a potential drop site. Both types of adorners can be customized.

A custom drag adorner is defined for an element which is a drag source via the attached property DragDrop.DragAdornerTemplate. The value should be a DataTemplate. The DataTemplate’s binding element will be set to the data object being transferred, so all bindings should be set up accordingly. Here is an example of a custom drag adorner template. This is the drag adorner defined for the ColumnsPresenter which is part of the default AdvTree control template:

<DataTemplate x:Key="{x:Static dc:AdvTree.ColumnHeaderDragAdornerTemplateKey}">
    <Border Background="{Binding HeaderBackground}" BorderBrush="Black" BorderThickness="1" Padding="5,1">
        <TextBlock Text="{Binding Header}" />
    </Border>
</DataTemplate>

A custom drop adorner is defined for an element which is a drop target via the attached property DragDrop.DropAdornerTemplate. The value should be a DataTemplate. The DataTemplate’s binding source will be set to the data object being transferred, so all bindings should be set up accordingly. Here is an example of a custom drop adorner template. This is the drop adorner defined for the ColumnsPresenter which is part of the default AdvTree control template:

<DataTemplate x:Key="{x:Static dc:AdvTree.ColumnHeaderDropAdornerTemplateKey}">
    <Grid Margin="-5,0,0,1" IsHitTestVisible="False">
        <Rectangle Margin="0,0,0,3" HorizontalAlignment="Center" Width="3" Fill="Blue" />
        <Path VerticalAlignment="Bottom" Fill="Blue" Data="M 0,0 L 10,0 5,5 Z" />
    </Grid>
</DataTemplate>

Note: It is also possible to set up a custom drag adorner in a custom DragHandler, and a custom drop adorner can be set up in a custom DropHandler.

Custom Handlers

The basic logic for a drag operation is provided by a DragHandler. Similarly, the logic which supports a drop target is provided by a DropHandler. As mentioned above, default DragHandlers and DropHandlers are already defined which work for most ItemsControl based controls as well as the AdvTree control. The existing handlers can be modified to handle special cases or new ones created for controls for which no handlers currently exist.

A custom drag handler is defined for an element which is a drag source via the attached property DragDrop.DragHandler. All drag handlers must derive from the abstract base class DevComponents.WPF.Controls.DragHandler. Currently existing drag handlers are: ColumnsPresenterDragHandler, AdvTreeDragHandler, AdvGridDragHandler and ItemsControlDragHandler.

A custom drop handler is defined for an element which is a drop target via the attached property Drag.DropHandler. All drop handlers must derive from the abstract base class DropHandler. Currently existing drop handlers are: ColumnsPresenterDropHandler, ItemsControlDropHandler, AdvTreeDropHandler and AdvGridDropHandler.

The sample project DragDropSample has example of both custom drag handler and custom drop handler.

Related posts:

  1. WPF RadialMenu Quick Start Guide
  2. WPF AdvToolBar Quick Start Guide
  3. WPF AdvTree Quick Start Guide
  4. WPF AdvGrid Quick Start Guide
  5. DataForm Quick Start Guide