Drag and Drop Operation in Silverlight ListBox



In this article, I am going to discuss with you regarding the Drag and Drop functionality inside a Silverlight ListBox control. This article will also cover the Drag and Drop operation between two ListBox control. We will use here the Silvelright 4 Toolkit to implement the feature.


Drag & Drop functionality is not present in Silverlight ListBox by default. Hence, there was a big problem implementing the feature. We had to write a huge code for this feature. But using Silvelright Toolkit you can do it very easily. You can download the Silverlight 4 Toolkit from the CodePlex Silverlight Toolkit site.



Using the code 
Silverlight 4 Toolkit has a control named ListBoxDragDropTarget which has the functionality for doing the Drag & Drop operation inside a ListBox control. Let us start creating our sample application with two ListBox control and populate one of them with some dummy data. We will be able to drag the ListBox element within the same ListBox control and also can be able to drop it into the second ListBox control.
  • First of all, create a Silverlight Application named "Silverlight4.DragDropListBox".
  • Now, right click on the Silverlight project and click "Add Reference". From the "Add Reference dialog add the Silverlight Toolkit assembly reference in your project. Once you are done with adding the assembly reference, you can use it anywhere inside your application.
  • Now open the MainPage.xaml and add the Toolkit DLL reference inside it, so that, we can use the toolkit controls inside the page. Once added, it will look like this:
<UserControl x:Class="Silverlight4.DragDropListBox.MainPage"
     xmlns:toolKit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit">
</UserControl>

Here, the line mentioned below is the reference to the Silverlight Toolkit. We prefixed the reference with “toolkit”, so that, we can refer the Silverlight toolkit using the “toolkit:” keyword.

xmlns:toolKit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"

Let us add the “ListBoxDragDropTarget inside the Grid. Set the attribute “AllowDrop” to True. Once it is set to true, it will be able to catch the drop event inside the control.

<toolKit:ListBoxDragDropTarget AllowDrop="True">

</toolKit:ListBoxDragDropTarget>

Now we will add a ListBox inside the ListBoxDragDropTarget which we just added inside the XAML page. Set proper Height and Width of the ListBox control. Also, we will set the DisplayMemberPath=”Name”. This is because, we will fetch some dummy Person information and set the ItemSource of the ListBox to that data where the Person has a property named “Name”. The name of the person will be visible here in the drop down.

<toolKit:ListBoxDragDropTarget AllowDrop="True">
  <ListBox x:Name="customerListBoxMain" Height="200" Width="200"
           DisplayMemberPath="Name">
    <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Vertical"/>
      </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
  </ListBox>
</toolKit:ListBoxDragDropTarget>

Let us create another ListBox control surrounded with ListBoxDragDropTarget. Here also we will set the same properties as we mentioned discussed earlier.

<toolKit:ListBoxDragDropTarget AllowDrop="True">
  <ListBox Height="200" Width="200" DisplayMemberPath="Name">
    <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Vertical"/>
      </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
  </ListBox>
</toolKit:ListBoxDragDropTarget>

Once we are done creating the XAML view, we can go forward to fetch some data and set it to the Source of the first ListBox from code behind. Here is the sample code:

public partial class MainPage : UserControl
{
    public MainPage()
    {
         InitializeComponent();

         customerListBoxMain.ItemsSource = PersonDataProvider.GetData();
    }
}


Drag and Drop between two ListBox
Once our design and coding is done, we can run the Silverlight application to showcase our work. Press F5 to run the application inside a browser. Once loaded, you will see two Listbox controls available in the screen. One contains some dummy data and the another is empty.

DragDropListBox_1

Now, we will drag one element from the first listbox to outside. We will see that the mouse cursor changed to “Unavailable” icon. Once you release your mouse you will notice that the item was not dropped at the specific point. Why? Because we marked only the two Listbox controls as DropTarget.

DragDropListBox_2

Now again we will start the drag operation from the first listbox and this time we will drag it inside the second Listbox control. What happened? The mouse cursor now has a small arrow with it. This is notifying that the item can be drop here.

DragDropListBox_3

Just release the mouse cursor and you will see that the Element has been removed from the first listbox and added to the second list.

DragDropListBox_4


Drag and Drop within the same ListBox
Here we will see the drag and drop operation within the same ListBox control. Start dragging any element and move it upward or downward within the same ListBox control. You will see that, the cursor has been changed to drop icon i.e. an arrow near the cursor. Also, it will show you a line inside the ListBox. This is the place where the drag and drop operation is going to happen.

DragDropListBox_6

Release your mouse and you will see that the item has been moved to a new position.

DragDropListBox_7

If the list is too big and you want to reposition your element in a specific location down the list, just do a drag to the end. You will see the scrollbar already started the scrolling operation automatically.

DragDropListBox_8



Points of Interest
This is very useful when you want to do some drag and drop operation within a tree view or between listbox control. You will also find it useful while rearranging a list of items by the end user.

Please drop a line with your Feedbacks/Suggestions/Comments.
Thank you for reading my blog.

Click Here to Download the entire Source Code

25 comments

  1. can we able to drag controls like textbox button and other controls?

    ReplyDelete
  2. Yes, you can. Use behaviors for dragging and dropping any Silverlight controls.

    ReplyDelete
  3. Can you give a copy of same soln which can open in VS 2008.
    I dont have VS10 @ my machine

    ReplyDelete
  4. The code was implemented in VS2010 & Silverlight 4. You have to manually create the same with VS2008 & Silverlight 3. Do a search on net, if you can find some example.

    ReplyDelete
  5. Very good article Kunal, I tried drag and drop between 2 DataGrids. It worked fine. Now I want to drag fromm same Data grid and drop onto StackPanel.The drop event is not firing. Is there any key to this?

    ReplyDelete
  6. This is really good.

    The source code is working fine.
    I implemented in "childwindow", drag drop not taking place.

    Please help me out.

    Thanks in advance

    ReplyDelete
  7. Hi Karthik,

    The drag drop will not directly work in ChildWindow. You have to remove the dragging feature of ChildWindow first before implementing this. Read out my article on Non-Movable ChildWindow in this blog. You will get some idea.

    Cheers...
    ~Kunal

    ReplyDelete
  8. This seems not working when the data collection is available in ViewModel and using bindings, any idea

    ReplyDelete
  9. i face problem in silverlight ..how we show multple selected items in list box on popup window...plz help me..and send code on my id: raz.8888@gmail.com

    ReplyDelete
  10. Erik,
    Its pretty simple actually. After reading through all the different forums and msdn docs, I found a much easier way. I was able to update the index, or ordinal, of customers in a listbox by using the ItemDragCompleted event. In the event I stepped through the newly ordered listbox and update the customers ordinal by their new index in the listbox.

    Hope that helps!

    ReplyDelete
  11. the link http://cid-5c93c05515dfe04a.skydrive.live.com/self.aspx/My%20Blog%20Share/Silverlight4%20DragDropListBox%20Demo.zip
    contains corrupted zip files(says no files inside)...

    ReplyDelete
  12. So is this just Moving the DataContext of the ListBoxItem from the one ItemsSource to another? How can I get/set the Data being moved around?

    ReplyDelete
  13. Hi Kunal,
    Though example shown for dropdown is pretty easy, there are lot of thing happening behind the scenes. Is it flexible enough for customizations? I found drag & drop from telerik here http://www.telerik.com/help/silverlight/raddraganddrop-between-listboxes-with-user-feedback.html

    It has handle of 4 events which we can use as per needs. Your comments on this?

    ReplyDelete
  14. Yes, I already have a post on Telerik Drag and Drop here: http://www.kunal-chowdhury.com/2009/12/silverlight-drag-and-drop-listboxitem.html. Have a look.

    ReplyDelete
  15. I just tried the example. I was getting weird behavior; the order not changing in the original list, when moving from one list to the other the item would not remove from the original list and depending on how I set up the list box, the app would crash when I tried to change the order in the original list. It wasn't until I downloaded the source code and analyzed it that I realized that my collection was the problem. I was binding to a custom collection that inherited from generic collection. This example was using generic observablecollection. Once I inherited from generic observablecollection, everything started working as advertised.

    ReplyDelete
  16. Hello Carl,

    Yes because OservableCollection internally fires the collection changed event to the UI thread and thus you don't have to explicitly refresh the binding.

    In your case, as you were not notifying the UI thread that a modification to the collection has happen, the items were in the same position. While changing the order, it creates a new copy of the item. Thus the item already exist in the UI and hence you are getting an exception which causes the app to crash.

    As you later used ObservableCollection from the demo code, everything works find because of the notification mechanism. Try to use this collection in Silverlight whenever require.

    ReplyDelete
  17. Hi Kunai,

    I have been all over the net looking for a example
    of what you are showing above. But where the two classes are different.
    For example you are binding to the Person class. What happens when one listbox is bound to the person class and the other listbox bound to a different class. but can accept a person?

    Thanks

    Louis

    ReplyDelete
  18. how i can implement the same in windows phone... U please help me i m on a deadlock sitwation. In my curent app i am using the same functionality. so you pls pls help me... or give me the guidelines to impement the same. my email id is stezma@gmail.com

    ReplyDelete
  19. Very nice, i have implemented it... problem is how to get dropped items ? i have a button, when you click on it i need items in 2nd list box... i want observablecollection(T)... can you tell me...

    ReplyDelete
  20. Is there a way of saving the newly arranged items order? Is it posible to bind the index of the position of the listbox item to a database?

    ReplyDelete
  21. Hi,

    Could you please tell me how to drag a line from one control(rectangle) to another control(rectangle) like the matching we do in school.i am doing this in c# 2012 for windows phone.
    Please give me suggestions.

    ReplyDelete
  22. This comment has been removed by the author.

    ReplyDelete
  23. Hi kunal-chowdhury ,

    Can we Develop Same Drag and drop in Windows Phone 8 , is this Possible

    ReplyDelete


 
© 2008-2014 Kunal-Chowdhury.com | Designed by Kunal Chowdhury
Back to top