Click here to Skip to main content
Click here to Skip to main content

DragSource - A WPF drag and drop helper

, 17 Jul 2013 Ms-PL
Rate this:
Please Sign up or sign in to vote.
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.

<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.

<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.

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.

/// <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.

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

        // Initializes the DataContext.
        DataContext = new SampleDataContext();
    }
}
<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.

<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)

Share

About the Author

JO Hyeong-Ryeol
Software Developer
Korea (Republic Of) Korea (Republic Of)
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141216.1 | Last Updated 17 Jul 2013
Article Copyright 2013 by JO Hyeong-Ryeol
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid