Drag Drop using Listboxes - Part 1
Drag Drop in WPF is not so complex once you get used to it…. Usually people blog on how to do drag drop with a canvas, I decided to do the drag drop for 2 listboxes since I think it can be more useful to application developers… + a friend, David Silverlight asked me about it so I decided to blog on it
So for our Drag and Drop exercise we will have 2 Listboxes. A “source” listbox and a “destination” listbox, so that the user can grab an item from the source and put it inside the destination listbox… In order to grab the item from the source listbox we need to handle the PreviewMouseLeftButtonDown event so that when the user holds the mouse left button down we can grab the item. Yet as you might be wondering we need to get the actual UI Element that the user selected (and then get the Content value). For this operation I created a helper method which you can see below…
This method will get a UIElement by using hit testing from the point that you specify. Yet if you set a breakpoint and look at the result of the Hit test you will find out that the value that you get from the Hit Test is one of the inner control of the ListBoxItem and not the actual ListBoxItem (for example if you have a TextBlock inside your ItemTemplate of the listbox, you would get the TextBlock). So we need to climb the WPF Visual Tree until we find the ListBoxItem. We are going to do this by trial and error. So we get the UIElement from the Hit Test and pass it to the ItemsContainerGenerator to give us the object source of the ListBoxItem that we are passing. If we do not pass the correct element (i.e if the element that we pass is not the ListBoxItem) the ItemsContainerGenerator will give us back DependencyProperty.UnsetValue, if the return is that we get the Parent from the Visual Tree and try again… Quite simple…
Now that we can get the object value from a point we can grab that value and do the drag drop operation. In order to do this we need to handle the PreviewMouseLeftButtonDown of the “source” listbox as follows
So here we grab the object from the “source” ListBox that we want to put in the “destination” ListBox. Then we call the DoDragDrop and pass the source listbox, the data to send in the DragDrop operation and the DragDrop effects.
Now lets implement the Drop. We have to create an event handler for the Drop event of the “destination” ListBox like the following
So in the event handler of the Drop all we are doing is to get the data that we passed over with the Drag Drop and push it in the Items collection of the “destination” Listbox. It is very important that to remove the Item from the “source” ListBox you use the ItemsSource and not the Items since that would throw an InvalidOperationException because you cannot change the Items collection while doing drag drop operation on the Listbox. Now it is also important to point out that if you remove an item from the ItemsSource but you ItemsSource is not an ObservableCollection(or any other collection that implements the INotifyCollectionChanged interface), nothing will happen i.e the item will not be removed from the source listbox. Basically by changing the ItemsSource we are relying on the DataBinding for the item to be removed…
I created a demo application for this article and also for Part 2 that I will be writing very soon… maybe even tonight
Part 2 will be more advanced… It will demo on how one can give a preview of the element while dragging to the other ListBox…
Regards








[...] Drag Drop using Listboxes - Part 2 In this post I will demo on how one can create a more advanced Drag Drop for ListBoxes than the one I posted earlier here. [...]