Bookmark and Share Share...    Subscribe to this feed Feed   About Christian Moser  


Drag and Drop in WPF

Introduction

Drag&Drop can drasticly improve the productiviy and user experience of a software. But only a few programmers provide drag and drop functionality in their applications, because they think its much more dificult than it really is. This article shows how simple drag and drop can be implemented in WPF.

Drag&Drop in 6 Steps

  1. Detect a drag as a combinatination of MouseMove and MouseLeftButtonDown
  2. Find the data you want to drag and create a DataObject that contains the format, the data and the allowed effects.
  3. Initiate the dragging by calling DoDragDrop()
  4. Set the AllowDrop property to True on the elements you want to allow dropping.
  5. Register a handler to the DragEnter event to detect a dragging over the drop location. Check the format and the data by calling GetDataPresent() on the event args. If the data can be dropped, set the Effect property on the event args to display the appropriate mouse cursor.
  6. When the user releases the mouse button the DragDrop event is called. Get the data by calling the GetData() method on the Data object provided in the event args.

...and that's all the magic.

Drag

To start the drag operation, we have to detect a mouse move while the left mouse button is pressed. To do this we have to hook up handlers on the PreviewMouseMove and PreviewMouseLeftButtonDown events.

To prevent occasionally drags, its a good design to not start the drag operation until the user has moved the mouse cursor by a couple of pixels. WPF provides a constant that contains the amount of pixel that Windows uses.

When the drag is initiated, we need to specify the data we want to drag. In our case its the data of the ListViewItem we dragged. We find the ListViewItem in the OriginalSource of the mouse event args. By calling ItemContainerGenerator.ItemFromContainer we get the data behind the ListViewItem.

Create a DataObject to transport the data to the drop location. The constructor takes two arguments. A string that describes the format and the data we want to drag.


 
<ListView x:Name="DragList" 
          PreviewMouseLeftButtonDown="List_PreviewMouseLeftButtonDown" 
          PreviewMouseMove="List_MouseMove"/>
 
 
 
private void List_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // Store the mouse position
    startPoint = e.GetPosition(null);
}
 
 
 
private void List_MouseMove(object sender, MouseEventArgs e)
{
    // Get the current mouse position
    Point mousePos = e.GetPosition(null);
    Vector diff = startPoint - mousePos;
 
    if (e.LeftButton == MouseButtonState.Pressed &&
        Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
        Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance )
    {
        // Get the dragged ListViewItem
        ListView listView = sender as ListView;
        ListViewItem listViewItem = 
            FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);
 
        // Find the data behind the ListViewItem
        Contact contact = (Contact)listView.ItemContainerGenerator.
            ItemFromContainer(listViewItem);
 
        // Initialize the drag & drop operation
        DataObject dragData = new DataObject("myFormat", contact );
        DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Move);
    } 
}
 
 
 
// Helper to search up the VisualTree
private static T FindAnchestor<T>(DependencyObject current)
    where T : DependencyObject
{
    do
    {
        if( current is T )
        {
            return (T)current;
        }
        current = VisualTreeHelper.GetParent(current);
    }
    while (current != null);
    return null;
}
 
 

Drop

To make an element be a drop location, set the AllowDrop property to true. When the user drags an item over the element, the DragEnter event is called. In this event you can analyze the data and decide if a drop is allowed or not.

When the user releases the mouse button the Drop event is called. The data is available in the DataObject provided in the DragEventArgs.


 
<ListView x:Name="DropList" 
          Drop="DropList_Drop" 
          DragEnter="DropList_DragEnter" 
          AllowDrop="True" />
 
 
 
private void DropList_DragEnter(object sender, DragEventArgs e)
{
    if (!e.Data.GetDataPresent("myFormat") ||
        sender == e.Source)
    {
        e.Effects = DragDropEffects.None;
    }
}
 
 
 
private void DropList_Drop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent("myFormat"))
    {
        Contact contact = e.Data.GetData("myFormat") as Contact;
        ListView listView = sender as ListView;
        listView.Items.Add(contact);
    }
}
 
 




Last modified: 2011-04-19 16:59:14
Copyright (c) by Christian Moser, 2011.

 Comments on this article

Show all comments
Patricio...
Commented on 11.March 2009
This is a good explanation about drag and drop thanks
I just need to figure out how to detach the item from its parent
Roger
Commented on 11.March 2009
Where can i find the ListView Element? Is it part of the Silverlight Library? Do you have a Example in a Solution? thx
Lordsam
Commented on 13.March 2009
I need to make an object draggable (ex:rectangle) but at the same time (and that's the issue) on release the same object should go back to it's predefined place.
Damian...
Commented on 14.April 2009
I was looking for some simple example of drag and drop in WPF. This example is perfect :)
Tom
Commented on 29.April 2009
I was looking for a good, simple explanation as well, and this just fit perfectly. Thanks!
martin
Commented on 21.May 2009
very nice, helped a lot to do exactly what i wanted in very short time!
Deepa
Commented on 28.May 2009
Really nice job done. thanks a lot.
i want to create binary tree using drag and drop. can u help me for the same please
Sektor
Commented on 12.August 2009
I think, it'll be much easier to handle MouseDown event than only MouseLeftButtonDown.
What if user wanna drag-and-drop with right button? For instance, Microsoft Excel® allows extra options when user drags some range with right button down. When using MouseDown event handler, we can define what button user pressed with ChangedButton property of MouseButtonEventArgs. :)
John
Commented on 13.August 2009
Ill suck your dick man
mudboots
Commented on 26.August 2009
It's a quite simple and helpful example. Thanks for sharing it.
By the way, I think this part:
if (e.LeftButton == MouseButtonState.Pressed &&
Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance )
should be
if (e.LeftButton == MouseButtonState.Pressed &&
( Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance ) )
What do you think?
Shiv
Commented on 9.September 2009
Can I move(drag) more than one object(UIElement) simultaneously on the canvas. Above code works for single object but how can I do for multiple objects?
TreeMe
Commented on 25.September 2009
I tried to change your example to work with a treeview instead of a listview. I get an Exception in the PreviewMouseMove method saying it cannot cast at the ItemContainerGenerator part. Can you show a working TreeView example?

Thanks.
Rob
Commented on 14.October 2009
I don't know what half of this means but you're fu*king cute.
asaassa
Commented on 31.October 2009
asaa
ss
Commented on 4.November 2009
What is 'contact' in above code?
Joe Schmoe...
Commented on 18.November 2009
Okay, I'm not sure how well this feed is monitored judging by the comments but I'll give it a shot. This tutorial is helpful to a point but the situation that I am in is a little different than what you have. I am passing data from one control into another. How can I translate the XAML to code on the back end to facilitate the second half of this communication?

<ListView x:Name="DropList"
Drop="DropList_Drop"
DragEnter="DropList_DragEnter"
AllowDrop="True" />

Where I need in the Code customControl.dropList.AllowDrop = true;
customControl.dropList.DragEnter += new DragEventHandler(DropList_DragEnter);
customControl.dropList.Drop += new DragEventHandler(DropList_DragEnter);
Joe Schmoe...
Commented on 19.November 2009
Okay, I'm not sure how well this feed is monitored judging by the comments but I'll give it a shot. This tutorial is helpful to a point but the situation that I am in is a little different than what you have. I am passing data from one control into another. How can I translate the XAML to code on the back end to facilitate the second half of this communication?

<ListView x:Name="DropList"
Drop="DropList_Drop"
DragEnter="DropList_DragEnter"
AllowDrop="True" />

Where I need in the Code customControl.dropList.AllowDrop = true;
customControl.dropList.DragEnter += new DragEventHandler(DropList_DragEnter);
customControl.dropList.Drop += new DragEventHandler(DropList_DragEnter);
GUSTAVO...
Commented on 22.November 2009
COMO HAGO PARA HACER DRAG AND DROG A UN VIEWPORT3D EN UNA APLICACION WPF PERO NECESITO HACERLO CON LENGUAJE DE VISUAL BASIC.NET CON ESE LENGUAJE NECESITO HACERLO LES AGRADECERIA QUE ME ENVIARAN UN EJEMPLO DE WPF PERO CON VISUAL BASIC.NET

GRACIAS POR LA AYUDA DIOS LES BENDIGA
amit
Commented on 15.December 2009
will you please tell that what is Contact in this article
is it user defined or something else
what is it's data type
abc
Commented on 15.December 2009
what is contact in this article??
PPShoo
Commented on 18.December 2009
In this example, Contact is the user defined class to hold the data or set of data that you want to transfer between two controls. You can create new class to fit your need. BTW, this is excellent article. I applied this technique to drag/drop for my treeviews. Have some issue though, after the drop event is handled, somehow the MouseMove event is invoked again and causes error. Anyone any clue?
srikanthReddy
Commented on 22.December 2009
As per your example, i Created one listBox and Canvas under DockPanel.ListView contains Multiple ListViewItems (Buttons). My Aim is Drag ListViewItems(Buttons) in to canvas. When i am implemented the logis i the below error is populating.

"Specified Visual is already a child of another Visual or the root of a CompositionTarget" Could you please suggest.
ram
Commented on 30.December 2009
this is wonderful article posted
kw
Commented on 4.January 2010
Very nice tutorials, keep up the good work.
You misspelled "ancestor" though, might want to correct that
Amitha
Commented on 4.January 2010
I have a datagrid which has a column header.I am dragging the header to another panel and the header text needs to be used for some purpose.But I am not able to drag the column header out of the grid.i shows the restricted cursor.
kartik
Commented on 20.January 2010
I want to select multiple items from Listview and drag drop it to another Listview .Do you have any code for that

Thanks in Advance
kartik
Commented on 20.January 2010
I want to select multiple items from Listview and drag drop it to another Listview .Do you have any code for that

Thanks in Advance
johnny
Commented on 29.January 2010
mud boots, you are right about the below, I was dragging straight horizontal and thought there was a bug, I should have read all the comments before checking myself. Anyways, I think there is a slight chance this could erroneously trigger the drag drop process... Technically, the startPoint should be Nullable and also should have preview mouse up set it to null and check for it....
Roel F
Commented on 29.January 2010
I'll try to clear it up here... Please correct me if I'm wrong:
'Contact' is a custom datatype I assume. It is the data behind the ListViewItem (see comments in the code). If there is just a string in there, use string instead of Contact.
Also, the error 'Specified Visual is already a child of blabla...' is exactly what it says: an element cannot be part of two different parent elements. So add code to remove the element form the first list before it is added to the second. eg: firstList.Items.Remove(item);

Hope this helps...
Sukanya Reddy
Commented on 9.February 2010
very nice article posted. really helped me a lot.thank you very much.
Studentus Askus
Commented on 21.February 2010
Can somebody post examples of Contact?
RomanK
Commented on 3.March 2010
Yes, an example for Contact (a class?) would be nice...
great tutorial except from that ;)
Daniel
Commented on 10.March 2010
From above code
// Find the data behind the ListViewItem
Contact contact = (Contact)listView.ItemContainerGenerator.
ItemFromContainer(listViewItem);

Here contact is the data class which is the data item of ListView.

Look at below code
-----------------------
private void List_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("myFormat"))
{
Contact contact = e.Data.GetData("myFormat") as Contact;
ListView listView = sender as ListView;
listView.Items.Add(contact);
}
}
-------------------------
The Contact class data object will be droped to listview
aryszka
Commented on 10.March 2010
i recommend to have a look at the DragLeave event or OnDrageLeave fire method as an alternative for drag section
Mike
Commented on 14.March 2010
If someone has an example of a "Contact" class please email me at
Michael.Splawski@gmail.com
Junkyard
Commented on 16.March 2010
@Mike:

class Contact { }

Hope that helps!
SorryAssWPFD...
Commented on 23.March 2010
Nice one however very incomplete. A pointer to the contact class would be nice.
Atul Raina
Commented on 28.March 2010
Awesome introduction, that is a building block for my quest to explore WPF
Jeff
Commented on 28.April 2010
private void List_PreviewMouseMove(object sender, MouseEventArgs e)
{
//// Get the current mouse position
Point mousePos = e.GetPosition(null);
Vector diff = lstSourceStartPosition - mousePos;

if (e.LeftButton == MouseButtonState.Pressed && Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
// Get the dragged ListViewItem
ListView listView = sender as ListView;

var items = listView.SelectedItems.Cast <Contact>();

var listOfItems = items.ToList();

if (listOfItems.Count == 0)
return;


// Initialize the drag & drop operation
DataObject dragData = new DataObject("items", listOfItems);
DragDrop.DoDragDrop(listView, dragData, DragDropEffects.Move);
}

}
Someone Else
Commented on 28.April 2010
Seriously, you need to know what the contact class looks like? You might want to reconsider a different career and not programming.
asd
Commented on 4.May 2010
I recommend to obtain the ListViewItem in List_PreviewMouseLeftButtonDown (and store them in some instance member). I ran into problems with your code (obtaining the item in List_MouseMove) if I drag the item pretty fast.

In my test scenario the e.OriginalSource was the ListView itself - so no chance to get the item by iterate through all visual parents. If I drag the item slowly your code works fine.
asd
Commented on 4.May 2010
I recommend to obtain the ListViewItem in List_PreviewMouseLeftButtonDown (and store them in some instance member). I ran into problems with your code (obtaining the item in List_MouseMove) if I drag the item pretty fast.

In my test scenario the e.OriginalSource was the ListView itself - so no chance to get the item by iterate through all visual parents. If I drag the item slowly your code works fine.
gen
Commented on 14.May 2010
How come FindAnchestor throws an error in my code?
gen
Commented on 14.May 2010
oops sorry wasn't able to read the whole code snippet before I commented... was so excited didn't even notice the definition below...
John
Commented on 14.May 2010
has anyone tried to drag and drop the treeviewitem? it seems to be a bug here. i called TreeView.ItemContainerGenerator.ItemFromContainer(treeViewItem), i got null.now i do not know jet how to resolve this problem.SOS
John
Commented on 14.May 2010
private void TreeView_Drop(object sender, DragEventArgs e)
{
TreeView tree = sender as TreeView;
DependencyObject dpo=VisualTreeHelper.HitTest(tv,e.GetPosition(tv)).VisualHit as DependencyObject;
while(dpo.GetType()!=typeof(TreeViewItem)) {dpo=VisualTreeHelper.GetParent(dpo);}
TreeViewItem tvi=dpo as TreeViewItem; //tvi ok
MyItemData mid=tree.ItemContainerGenerator.ItemFromContainer(tvi) as MyItemData ; //false! mid=null
//in the fact, tree.ItemContainerGenerator.ItemFromContainer(tvi).GetType() is MS.Internal.NamedObject
......
}
John
Commented on 14.May 2010
i want just to change the branch structure of a treeview with the help of drag-and-drop. it goes on wheels with WindowForms programming.But here with WPF it comes hard.so it is sure that i am not familiar enough with WPF.
John
Commented on 14.May 2010
ha,TreeViewItem.DataContex !
john
Commented on 14.May 2010
thanks,i have got inspiration from your site!
John
Commented on 14.May 2010
Please help me! after drag-n-drop of one node some of the nodes disappear weirdly. it drive me mad. i can not understand this. here is all the code. i beg for your help.
public class TreeNode
{
BindingList<TreeNode> lst = new BindingList<TreeNode>();
Guid id = Guid.NewGuid();
public Guid ID { get { return id; } }
public TreeNode Parent { get; set; }
public BindingList<TreeNode> Children { get { return lst; } }
}
public class TreeDataSource
{
public TreeDataSource()
{
TreeNode node = new TreeNode();
lst.Add(node);
for (int i = 0; i < 5; i++)
{
node.Children.Add(new TreeNode() { Parent = node });
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
node.Children[i].Children.Add(new TreeNode() { Parent = node.Children[i] });
}
}
}
BindingList<TreeNode> lst = new BindingList<TreeNode>();
public BindingList<TreeNode> Children { get { return lst; } }
}
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:this="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<HierarchicalDataTemplate DataType="{x:Type this:TreeNode}" ItemsSource = "{Binding Path=Children}">
<TextBlock Text="{Binding Path=ID}"/>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView Grid.Row="0" ItemsSource="{Binding Path=Children}" AllowDrop="True" Name="tree"/>
</Grid>
</Window>
public partial class Window1 : Window
{
const string myData = "myData";
public Window1()
{
InitializeComponent();

DataContext = new TreeDataSource();

tree.AddHandler(TreeView.MouseLeftButtonDownEvent, new MouseButtonEventHandler(TreeView_MouseLeftButtonDown), true);
tree.AddHandler(TreeView.MouseLeftButtonUpEvent, new MouseButtonEventHandler(tree_MouseLeftButtonUp), true);
tree.AddHandler(TreeView.MouseMoveEvent, new MouseEventHandler(tree_MouseMove), true);
tree.AddHandler(TreeView.DropEvent, new DragEventHandler(TreeView_Drop), true);
}

Rect rectMouseDown = Rect.Empty;
void tree_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
rectMouseDown = Rect.Empty;
}
void tree_MouseMove(object sender, MouseEventArgs e)
{
Point p=e.GetPosition(null);
if (rectMouseDown != Rect.Empty && rectMouseDown.Contains(p) == false)
{
TreeView tree = sender as TreeView;
TreeNode node = GetNodeData(tree, p);
if (node != null)
{
DataObject data = new DataObject(myData, node);
DragDrop.DoDragDrop(tree, data, DragDropEffects.All);
}
}
}
private void TreeView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
TreeView tree = sender as TreeView;
Point p = e.GetPosition(null);
TreeNode node = GetNodeData(tree, p);
rectMouseDown = node == null ? Rect.Empty : new Rect() { X = p.X - 2, Y = p.Y - 2, Width = 4, Height = 4 };
}
private void TreeView_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(myData))
{
TreeNode beDragged = e.Data.GetData(myData) as TreeNode;

TreeView tree = sender as TreeView;
TreeNode newFather = GetNodeData(tree, e.GetPosition(tree));

if (newFather != null)
{
TreeNode father = beDragged.Parent;
father.Children.Remove(beDragged);
beDragged.Parent = newFather;
newFather.Children.Add(beDragged);
}
}
}
TreeNode GetNodeData(TreeView tree, Point p)
{
TreeNode node = null;
DependencyObject dpo = VisualTreeHelper.HitTest(tree, p).VisualHit as DependencyObject;
if (dpo != null)
{
while (dpo != null && dpo.GetType() != typeof(TreeViewItem)) dpo = VisualTreeHelper.GetParent(dpo);
if (dpo != null) node = (dpo as TreeViewItem).DataContext as TreeNode;
}
return node;
}
}
Carlos Oviedo
Commented on 14.May 2010
Please!! in VB .NET
Carlos Oviedo
Commented on 14.May 2010
Please!! in VB .NET
Kobe Bryant
Commented on 15.May 2010
I want to drag and drop an object with multipoint sdk. How must I do?
Mick
Commented on 19.May 2010
Just reading through your sample, I noticed && should probably be ||, or else the user can drag horizontally/vertically forever without calling DoDragDrop.

Aside from that, it was very clean and easy to understand. Thank you.
Scrut
Commented on 19.May 2010
If you want to disallow dropping in certain areas, WPF requires you to implement the DragOver and DragLeave as well: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/38231053-01d4-4b58-b994-7bf3d2e4a73e

Good work
Brian Finn
Commented on 26.May 2010
If you use a Canvas as droptarget, you'll have to set the Background-Property to let it work.
Barak (Israel)
Commented on 6.June 2010
I think you should replace the && with ||:

replace: Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance )

with: Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance )

Mark
Commented on 7.June 2010
Awesome, superb, incredible. In an immense OCEAN of disinformation and convoluted examples, you have provided a rare treasure of clear and concise information. Bravo !!! Thank you so much ! Note, though. My Lisview is bound to a collection so I will have to do additional work to get this working.
Mayank
Commented on 12.June 2010
Cannot find CONTACT class and startpoint refrence. Please help
krishna
Commented on 16.June 2010
Hi all,
Am totally new to Wpf ,i tried to execute this code but it is not working..
The Events are not firing at all...
Wat did i missed???
Can any one send me a complete source code....
Thanks in Advance...
krishna
Commented on 16.June 2010
Hi all,
Am totally new to Wpf ,i tried to execute this code but it is not working..
The Events are not firing at all...
Wat did i missed???
Can any one send me a complete source code....
Thanks in Advance...
shafqat ali
Commented on 21.June 2010
Nice article. But i can't find reference classe. Please send me completed source code.
Thanks, Shafqat.
Kandhal Rohit
Commented on 29.June 2010
http://www.codeproject.com/KB/WPF/WpfDragAndDropSmorgasbord.aspx

Check this link. It has everything you would ever dream about Drag and Drop functionality.
Florian
Commented on 8.July 2010
Hej!
I have the same problem like Mayank. Can someone help us with this problem?
Msh
Commented on 12.July 2010
it is ok
LandR
Commented on 14.July 2010
I have a tree view bound to hierarchical data that I've created in Blend 4. I want to be able to do this:

Let's say the tree breaks down fruit and vegetables. Under the expanded veggies tree, I want to be able to see all vegetables - fruit the same. But say tomato is under vegetables, and I want it under fruit, in the same tree (different branch). I want to be able to click on "tomato" and drag and drop it on "fruit" and have it move that entry to "fruit" and update my database (2 way link).

+fruit

1. apples
2. oranges

+ vegetables

1. onion
2. spinach
3. tomato

(drag and drop tomato)

+fruit

1. apples
2. oranges
3. tomato

+ vegetables

1. onion
2. spinach

Any thoughts?

Thanks!
NONE OF THIS...
Commented on 23.August 2010
COPYRIGHT INFRINGEMENT AT ITS FINEST!!!!!!!!!

MOSER IS GREASY AS HELL
C-MOSE
Commented on 23.August 2010
I apprieciate your feedback but I cant explain it anymore in depth because I just copy and pasted this from another website
Purple
Commented on 15.September 2010
I try to write it in VB but I dont understand this code:

ListViewItem listViewItem =
FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);

private static T FindAnchestor<T>(DependencyObject current)
where T : DependencyObject
{
do
{
if( current is T )
{
return (T)current;
}
current = VisualTreeHelper.GetParent(current);
}
while (current != null);
return null;
}


My purpose is dragging a custom object with image from listbox to a canvas
Software...
Commented on 15.September 2010
Apart from PreviewMouseLeftButtonDown, none of the event is firing... I copied all your code as it is in my usercontrol, but I am not able to fire any other event.

I am looking forward to your help.
Software...
Commented on 15.September 2010
Apart from PreviewMouseLeftButtonDown, none of the event is firing... I copied all your code as it is in my usercontrol, but I am not able to fire any other event.

I am looking forward to your help.
serhio
Commented on 20.September 2010
this is pretty cool for data drag/drop. But What if I need to drag a userControl on a Canvas?
Asghar Panahy
Commented on 4.October 2010
How would you drag a window, like repositioning it?
john earl...
Commented on 20.October 2010
I had stroke and so confused
Gregory
Commented on 15.November 2010
Where are the F***ING copyrights ? You place the article as it is yours, but you have just stolen it
BG
Commented on 17.November 2010
Great article. Very helpful! Thanks much!
Mister...
Commented on 18.January 2011
Anyone could have written these few lines of code, don't act like it is priceless.
You should be happy someone is taking some time to educate us noobs!
siva
Commented on 9.February 2011
Hi, I need to drag an item from the list box and drop it on the media element.is it possible to do that,if it please explaint with sample code.

Thanks in advance.
MM
Commented on 10.February 2011
Tell that to this guy...

dotnetspider (dot) com/resources/26044-Drag-Drop-WPF.aspx
Vladimir36
Commented on 15.February 2011
This shit does not work.
abc
Commented on 23.February 2011
this article is exactly the same, but posted earlier. hmmm.
www dotnetspider com/resources/26044-Drag-Drop-WPF.aspx
Paul
Commented on 28.February 2011
Its copied like googleberg:
www.dotnetspider (dot) com/resources/26044-Drag-Drop-WPF.aspx
and you do everything that noone can past a link. Zülke ist great!
Bob
Commented on 3.March 2011

Will everyone stop moaning, at least Christian has made the effort to try and educate us. He at no point says itâs his code and in fact if you read up the thread he states âI just copy and pasted this from another websiteâ. Thanks for gathering all of this WPF stuff Christian, great job!

Norbert
Commented on 4.March 2011
Worked great!

Very nice example and very easy to implement.

Thank-you!
_nkidu
Commented on 9.March 2011
In List_MouseMove the second and should be replaced by an or:

if (e.LeftButton == MouseButtonState.Pressed &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance ))
{
[...]
}
_nkidu
Commented on 9.March 2011
In List_MouseMove the second and should be replaced by an or:

if (e.LeftButton == MouseButtonState.Pressed &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance ))
{
[...]
}
Honesty...
Commented on 17.March 2011
Bob: "He at no point says it's his code"? The main article doesn't mention the copying so he is implicitly claiming that it's his code to anyone who doesn't read the comment thread.
Guest
Commented on 22.March 2011
COPYRIGHT INFRINGEMENT.

Christian Moser, the author of this page, is not honest. He copied and pasted the article, but didn't mention the actual author and the source along with it. Convenient way to let everybody believe he is the author. Such a shame.
Christian Moser
Commented on 22.March 2011
<p><b>Just to clarify. I am the original author of this article! Prajeesh Prabhakar just copied and pasted it on www.dotnetspider.com. He did not even care about the bold words or the numbered lists that got lost in the copy!</b></p>
<p>Please do not blame me before carefully checking it is true. I wrote to the autor to immediately remove the content. This is not fairplay.</p>
Guest
Commented on 25.March 2011
You're quick at filtering out certain comments.

If you are the author of this article, please add the clarification at the beginning of the article and not dropped somewhere among other comments.
Christian Moser
Commented on 27.March 2011
I don't need to justify, that I am the author of my own article. <br><b>Please note that the copy on <a href="http://www.dotnetspider.com/resources/26044-Drag-Drop-WPF.aspx">dotnetspider.com</a> has been rejected due to "Reproduced content".</b>
Olivier
Commented on 31.March 2011
Great article, i could implement a drag and drop between Datagrids based on it.
I only found one small issue in the IF condition. You'll need to add some bracket to oppose the LeftButton.Pressed and the movement of the mouse.

Original:
if (e.LeftButton == MouseButtonState.Pressed &amp;&amp;
Math.Abs(diff.X) &gt; SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) &gt; SystemParameters.MinimumVerticalDragDistance )
Modified:
if (e.LeftButton == MouseButtonState.Pressed &amp;&amp; (
Math.Abs(diff.X) &gt; SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) &gt; SystemParameters.MinimumVerticalDragDistance )
)
Pat Tormey
Commented on 31.March 2011
WOW Dude, they jumped all over you and didn't even have guts to admit they were wrong..
Maybe it's early yet..
John
Commented on 31.March 2011
Thanks for the code and all the help with WPF!
Guest
Commented on 7.April 2011
I'm glad you noticed that the article has been removed from dotnetspider. For the record, it happened after my intervention (if interested, I can provide you with the conversation I had with the owner of the web site.) I wouldn't have done it if it wasn't a good article. It was creating confusion to the readers of this article.

I appreciate your time and effort for writing and making this article available.
Guest
Commented on 13.April 2011
The article is great. After trying it out, I found some little mistakes:
- method List_DragEnter must be called DropList_DragEnter
- method List_Drop must be called DropList_Drop
- in method DropList_DragEnter the code e.Data.GetDataPresent(&quot;contact&quot;) must be e.Data.GetDataPresent(&quot;myFormat&quot;)
Thanks a lot for the article.
khushal
Commented on 18.April 2011
Which Library are use for Contact
Christian Moser
Commented on 19.April 2011
Hi Guest,
thank you for your support on this dotnetspider thing. It was really annoying to get blamed for copyright violations on your own article.
Viru
Commented on 28.April 2011
Great work Christian, keep educating us. Don't listen to those bad people comments. In this world we have good and bad. Lister to good always. Once again thanks for your time and effort. May god Bless you.
Ashish
Commented on 5.May 2011
Hi Christian,

I had a question for you. I have a scenario where in there is a Window (Parent) having a DockGroup containing two Tabbed Panels. Now when I drag one of the tabs outside of the Parent Window, I want this dragged tab to change to a window in itself. e.g. the way Google Chrome Browser / Mozilla FireFox Browser has it implemented. Can you suggest of a way in which this can be implemented in WPF using C#.NET 4.0 ?
Will Bellman
Commented on 9.May 2011
Just digging into WPF Drag and Drop. Thanks for the article!
Claude
Commented on 17.May 2011
change soures

1.
Point startPoint;
private void List_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e){startPoint = e.GetPosition(null);}
//because ohter funcion need starpoint
//Vector diff = startPoint - mousePos;

2.
Contact change ListBoxItem
Swat
Commented on 20.May 2011
How to drag and drop a button?
Phil
Commented on 9.June 2011
I'm trying to use this (in Visual Basic) but I'm stuck because there doesn't seem to be a FindAncestor method? The only reference to it on MSDN says it's for Microsoft internal use only.
Guest
Commented on 9.June 2011
I like this drag-drop example: http://www.hardcodet.net/2009/03/moving-data-grid-rows-using-drag-and-drop
Phil
Commented on 10.June 2011
I'm trying to use this (in Visual Basic) but I'm stuck because there doesn't seem to be a FindAncestor method? The only reference to it on MSDN says it's for Microsoft internal use only.
Phil
Commented on 10.June 2011
I'm trying to use this (in Visual Basic) but I'm stuck because there doesn't seem to be a FindAncestor method? The only reference to it on MSDN says it's for Microsoft internal use only.
David C
Commented on 17.June 2011
I tried the same thing in the RightButton click but at that time DragOver event is not fired.. How can i resolve this problem ?
ZeePrime
Commented on 17.June 2011
Very Good.

Warning with the if, you miss a couple of brackets as &amp;&amp; has precedence over ||
if (e.LeftButton == MouseButtonState.Pressed &amp;&amp;
Math.Abs(diff.X) &gt; SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) &gt; SystemParameters.MinimumVerticalDragDistance )
kamlendra
Commented on 23.June 2011
how can i go for multiple drag and drop?? say i want to select three items @ a time from Drag_list and drop them into Drop_list.
oc
Commented on 27.June 2011
Hi,
I am trying out your code but in Datagrid not in Listview. I couldn't figure it out the 'Contact' in this line
Contact contact = (Contact)listView.ItemContainerGenerator.
what does it stands for ?
Regards
david
Commented on 20.July 2011
I agree with Olivier as for the missing parentheses in the mouseMove conditions. You should correct it in the main article :p
NIkhil
Commented on 21.July 2011
Hi Christian,

Please elaborate what is Contact used in 4 places in this example?
Contact contact = (Contact)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
Contact contact = e.Data.GetData(&quot;myFormat&quot;) as Contact;

Thanks in advance
KornMuffin
Commented on 28.July 2011
Sweet and simple. Thanks for the wealth of info on your site.

@oc - just use a string instead of the Contact class if you don't want to create your own Contact class.
tooma
Commented on 2.August 2011
i can smell poo and a small amount of wee too.
tooma
Commented on 2.August 2011
i can smell poo and a small amount of wee too.
seiko
Commented on 4.August 2011
Why i am getting this exception everytime?
Element already has a logical parent. It must be detached from the old parent before it is attached to a new one.

on line
listView.Items.Add(contact); ??
Somebody may know that?
bizzare
Commented on 17.August 2011
Hi,
Im a newbie to WPF and i dont know if this question even makes sense here but i dint know where else to post it! I need to select two or more items from a list box and then enable a button. Can you please help me as to how i could do it?Thanks!
bizzare
Commented on 17.August 2011
Hi,
Im a newbie to WPF and i dont know if this question even makes sense here but i dint know where else to post it! I need to select two or more items from a list box and then enable a button. Can you please help me as to how i could do it?Thanks!
Abhishek...
Commented on 17.August 2011
I m using very similar drag and drop functionality in my WPF app , while i wish to drag item from combobox to textbox , when im doing so , the combobox always get closed and i can't select any items from it to drag towards textbox.
bizzare
Commented on 17.August 2011
Hi,
Im a newbie to WPF and i dont know if this question even makes sense here but i dint know where else to post it! I need to select two or more items from a list box and then enable a button. Can you please help me as to how i could do it?Thanks!
bizzare
Commented on 17.August 2011
Hi,
Im a newbie to WPF and i dont know if this question even makes sense here but i dint know where else to post it! I need to select two or more items from a list box and then enable a button. Can you please help me as to how i could do it?Thanks!
Tom Pester
Commented on 21.August 2011
Contact is just a class (domain/poco)

public class Contact
{
public Contact(string firstname, string lastname)
{
Firstname = firstname;
Lastname = lastname;
}

public string Firstname { get; set; }
public string Lastname { get; set; }

public override string ToString()
{
return string.Format(&quot;Firstname: {0}, Lastname: {1}&quot;, Firstname, Lastname);
}
}

To get the code working I had to change the code from (this is a bug IMO)


if (e.LeftButton == MouseButtonState.Pressed &amp;&amp;
Math.Abs(diff.X) &gt; SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) &gt; SystemParameters.MinimumVerticalDragDistance
)
to
if (e.LeftButton == MouseButtonState.Pressed &amp;&amp;
(
Math.Abs(diff.X) &gt; SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) &gt; SystemParameters.MinimumVerticalDragDistance
)
)

I also got null reference exceptions and had to check the listViewItem for null:

ListViewItem listViewItem =
FindAnchestor&lt;ListViewItem&gt;((DependencyObject) e.OriginalSource);
if (listViewItem == null) return;

I think its due to a timing issue if you do a drag and drop very fast or execute the code on a fast computer?

Thanks for this minimal sample. It's excellent to get started from.
Lasoty
Commented on 22.August 2011
Hi!
Please show mi how look the Contact class.

TXH
Lasoty
Commented on 22.August 2011
Hi!
Please show mi how look the Contact class.

TXH
Guest
Commented on 5.September 2011
Hi!!
I am able to drag the control. but i have to drop the control to dynamically created Panel or Canvas. How i should proceed? Pls help me
Guest
Commented on 5.September 2011
Hi!!
I am able to drag the control. but i have to drop the control to dynamically created Panel or Canvas. How i should proceed? Pls help me
Guest
Commented on 5.September 2011
Hi!!
I am able to drag the control. but i have to drop the control to dynamically created Panel or Canvas. How i should proceed? Pls help me
Guest
Commented on 5.September 2011
Hi!!
I am able to drag the control. but i have to drop the control to dynamically created Panel or Canvas. How i should proceed? Pls help me
Guest
Commented on 5.September 2011
Hi!!
I am able to drag the control. but i have to drop the control to dynamically created Panel or Canvas. How i should proceed? Pls help me
Raman
Commented on 23.September 2011
Hi,

I have tried this program, just used the class &quot;People&quot; instead of &quot;Contact&quot; and it wors fine. Here is the code that I have tried for the &quot;People&quot;:

public class Person

{


private string _name;
private string _relationshipType;
public string Name
{
get { return _name; }
set
{
_name = value;
}
}
public string RelationshipType
{
get { return _relationshipType; }
set { _relationshipType = value; }
}
public Person(string name, string relationshiptype)
{
this._name = name;
this._relationshipType = relationshiptype;
}

}
public class People : ObservableCollection&lt;Person&gt;
{
public People()
{
Add(new Person(&quot;Sean&quot;, &quot;Friend&quot;));
Add(new Person(&quot;Chris&quot;, &quot;Friend&quot;));
Add(new Person(&quot;Peter&quot;, &quot;Brother&quot;));
Add(new Person(&quot;Jeremy&quot;, &quot;Brother&quot;));
Add(new Person(&quot;Kevin&quot;, &quot;Brother&quot;));
}
}

Regards
Patrick
Commented on 27.September 2011
Hello,
I tried to implement this and the button state is never pressed. Also my Clickevents don't trigger anymore. So drag and drop works or the Clickevent never both.
regards

Name
E-Mail (optional)
Comment