Click here to Skip to main content
15,886,720 members
Articles / Desktop Programming / WPF
Tip/Trick

DragSource - A WPF drag and drop helper

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
17 Jul 2013Ms-PL2 min read 15.5K   728   10  
Introduces the DragSource class in the Nicenis project.

Introduction

DragSource is a static class that helps to make a draggable element for drag-and-drop operation. This class is a part of the Nicenis project. You can find the latest information from the CodePlex project homepage at https://nicenis.codeplex.com.

Requirements

You have to reference the Nicenis.dll. .NET Framework 4 Client Profile or higher is also required.

Basic Usage

Two attached properties are required to be set at a minimum.

  • AllowDrag: Indicating whether the element is draggable.
  • Data: A data object that contains the data being dragged.

This is an example.

XML
<Window
    x:Class="DragSourceSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:n="clr-namespace:Nicenis.Windows;assembly=Nicenis"
    Title="MainWindow" Height="200" Width="200">

    <!-- This border will be draggable.-->
    <Border
        n:DragSource.AllowDrag="True"
        n:DragSource.Data="Test Data"
        Margin="30"
        Background="Green"
        />
</Window>

It will look like this image if you drag the border.

The position you click in the border is not preserved by default when it is dragged. You can use the following attached properties to solve it.

  • VisualFeedbackOffset: An offset that is pointed by a pointing device in the visual drag feedback.
  • ContactPosition: A readonly contact position in the dragged source.

This is a refined example.

XML
<Window
    x:Class="DragSourceSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:n="clr-namespace:Nicenis.Windows;assembly=Nicenis"
    Title="MainWindow" Height="200" Width="200">

    <!-- This border will be draggable.-->
    <Border
        n:DragSource.AllowDrag="True"
        n:DragSource.Data="Test Data"
        n:DragSource.VisualFeedbackOffset="{Binding (n:DragSource.ContactPosition), RelativeSource={RelativeSource Self}}"
        Margin="30"
        Background="Green"
        />
</Window>

Lazy Data Object Creation

You can set the Data attached property to an implementation of the IDataObjectProvider interface.

C#
namespace Nicenis.Windows
{
    /// <summary>
    /// Provides a way to get a data object that contains the data being dragged.
    /// </summary>
    public interface IDataObjectProvider
    {
        /// <summary>
        /// Gets a data object that contains the data being dragged.
        /// </summary>
        /// <returns>A data object that contains the data being dragged.</returns>
        object GetDataObject();
    }
}	

The GetDataObject method is called right before the drag-and-drop is started. A sample implementation is as follows.

C#
/// <summary>
/// A sample data context that implements the IDataObjectProvider interface.
/// </summary>
public class SampleDataContext : IDataObjectProvider
{
    public object GetDataObject()
    {
        return "Test Data";
    }
}

The following code shows how to bind it to a Data attached property.

C#
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Initializes the DataContext.
        DataContext = new SampleDataContext();
    }
}
XML
<Window
    x:Class="DragSourceSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:n="clr-namespace:Nicenis.Windows;assembly=Nicenis"
    Title="MainWindow" Height="200" Width="200">

    <!-- The Data is bound to an implementation of the IDataObjectProvider interface.-->
    <Border
        n:DragSource.AllowDrag="True"
        n:DragSource.Data="{Binding}"
        n:DragSource.VisualFeedbackOffset="{Binding (n:DragSource.ContactPosition), RelativeSource={RelativeSource Self}}"
        Margin="30"
        Background="Green"
        />
</Window>

 

Custom Visual Feedback

If you need to customize the dragged image called visual feedback, you can use the VisualFeedback attached property.

  • VisualFeedback: The content of the visual drag feedback.

The following code uses an ellipse as a custom visual feedback.

XML
<Window
    x:Class="DragSourceSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentationquot;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:n="clr-namespace:Nicenis.Windows;assembly=Nicenis"
    Title="MainWindow" Height="200" Width="200"
    >
    <Border
        n:DragSource.AllowDrag="True"
        n:DragSource.Data="Test Data"
        n:DragSource.VisualFeedbackOffset="70 70"
        Margin="30"
        Background="Green"
        >
        <!-- An ellipsis is set as a visual feedback.-->
        <n:DragSource.VisualFeedback>
            <Ellipse Fill="Red" Width="140" Height="140" />
        </n:DragSource.VisualFeedback>
    </Border>
</Window>

It will look like the following if you drag the border.

Visual feedback inherits data source's DataContext by default. You can override it by using the following attached property.

  • VisualFeedbackDataContext: An object that is set to the data context of the visual drag feedback.

If you want visual feedback templating, the following attached properties may help you.

  • VisualFeedbackTemplate: A data template for the content of the visual drag feedback.
  • VisualFeedbackTemplateSelector: A template selector for the content of the visual drag feedback.

 

Touch Not Ready

This class is not tested in a touch device yet.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Software Developer
Korea (Republic of) Korea (Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --