TreeView Drag Drop in Silverlight

Posted by: Suprotim Agarwal , on 5/19/2010, in Category Silverlight 2, 3, 4 and 5
Views: 61971
Abstract: I have seen plenty of questions around drag-drop operations within a TreeView and I thought of dedicating a post to it. This article shows you how easy it is now to do a Drag Drop operation on a TreeView in Silverlight
I have seen plenty of questions around drag-drop operations within a TreeView and I thought of dedicating a post to it. Now usually when one thinks of implementing a Drag Drop operation on a TreeView, there are a couple of events like the DragEnter, DragLeave, DragOver and Drop that are to be raised and handled. In some cases, you must also cancel the drag-n-drop operation if the drop is invalid. Overall, this looks like a lot of work for a developer who wants to quickly implement drag-n-drop functionality on his/her controls.
With the addition of the drag-drop targets for controls like the TreeView (and some others like the ListBox, DataGrid and DataPointSeries), doing a drag and drop operation in a TreeView is a cakewalk. Here’s a simple example:
Note: Make sure you have added a reference to the System.Windows.Toolkit. You can download the latest Silverlight toolkit over here
<UserControl
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
    x:Class="SilverlightDragDropTreeView.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="250" d:DesignWidth="300">
    <Canvas x:Name="LayoutRoot">
        <toolkit:TreeViewDragDropTarget AllowDrop="True" HorizontalContentAlignment="Stretch">
            <sdk:TreeView Height="250" >
                <sdk:TreeViewItem Header="Permanent">
                    <sdk:TreeViewItem Header="Jill"/>
                    <sdk:TreeViewItem Header="Yahana"/>
                    <sdk:TreeViewItem Header="Kapil"/>
                </sdk:TreeViewItem>
                <sdk:TreeViewItem Header="Temporary">
                    <sdk:TreeViewItem Header="Matthew"/>
                    <sdk:TreeViewItem Header="Sarak"/>
                    <sdk:TreeViewItem Header="Jack"/>
                </sdk:TreeViewItem>
            </sdk:TreeView>
        </toolkit:TreeViewDragDropTarget>
    </Canvas>
</UserControl>
 
As you can see, the TreeView control is wrapped inside a TreeViewDragDropTarget which has the UIElement.AllowDrop property set to True. The UIElement.AllowDrop property determines whether this UIElement can be a drop target for purposes of Silverlight drag-and-drop operations. Setting this property to true enables it to raise or handle events like DragEnter, DragLeave, DragOver and Drop.
That is all that is required to enable Drag-Drop operations on a TreeView. Run the code and you will see that you can drop items between the Permanent and Temporary Categories
Temporary
After dragging and dropping ‘yahana’ from Permanent to Temporary
Permanant
Binding the TreeView with a Parent-Child Collection Object
As you can observe, to keep this article simple and to the point, I have hardcoded the TreeViewItem’s in the markup. In a real world application, you will rarely do that. Instead you would want to bind a custom collection of objects to the TreeView.
Let’s walkthrough the logical steps to bind the TreeView to a collection of objects. This example assumes that there are two collections:
-      EmployeeCategory collection containing a EmpCategoryName property with two values, Permanent and Temporary
-      Employee collection within each EmployeeCategory containing EmployeeName field
Here’s some ‘psuedocode’ of what the EmployeeCategory class would look like
public class EmployeeCategory implements INotifyPropertyChanged
{
     public string EmpCategoryName { get; set; } // onPropertyChanged
     public List<Employee> _employees { get; set; } // onPropertyChanged
So each parent level of the TreeView will be bound to the EmpCategoryName property from the EmployeeCategory, whereas the second level will display the EmployeeName in each EmployeeCategory collection.  
To bind this collection to the TreeView, we will use a TreeView.ItemTemplate. Since we are using a Parent-Child relationship here, we will use two HierarchicalDataTemplate templates. Here’s how the markup would look like
<toolkit:TreeViewDragDropTarget AllowDrop="True" VerticalContentAlignment="Stretch">
        <toolkit:TreeViewDragDropTarget.Resources>
 
            <sdk:HierarchicalDataTemplate  x:Key="EmpCategory"
ItemsSource="{Binding Employee}" ItemTemplate="{StaticResource EmpNames}">
                 <TextBlock Text="{Binding EmpCategoryName}"/>
            </sdk:HierarchicalDataTemplate>
 
            <sdk:HierarchicalDataTemplate  x:Key="EmpNames"
                <TextBlock Text="{Binding EmployeeName}"/>
            </sdk:HierarchicalDataTemplate>
 
        </toolkit:TreeViewDragDropTarget.Resources>
 
        <sdk:TreeView x:Name="tView" ItemTemplate="{StaticResource EmpCategory}"
        Height="250" >
        </sdk:TreeView>
</toolkit:TreeViewDragDropTarget>
 
The data can be pulled using a WCF service which will query the EmployeeCategory and Employee classes and bind it to the TreeView. I hope these steps will guide you how to bind the TreeView to a custom collection object. Let me know if you need a complete article on this with the WCF service implementation and I will write one for you.
I hope this article was useful and I thank you for viewing it. The entire source code of this article can be downloaded over here

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for Sixteen consecutive years. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that offers Digital Marketing and Branding services to businesses, both in a start-up and enterprise environment.

Get in touch with him on Twitter @suprotimagarwal or at LinkedIn



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Mickey on Wednesday, May 19, 2010 5:40 AM
(taking a bow) Man you write so simple! It gets into my head instantly :)
Comment posted by Clay Fowler on Sunday, February 20, 2011 7:15 PM
What events are you supposed to bind to in order to make drag and drop work on a data bound TreeView? Dragging works on my TreeView but dropping has no effect (nodes don't move).
Comment posted by Ruchita on Wednesday, March 30, 2011 12:54 AM
Thanks Suprotim !
code is easy but i was unaware of this silverlight control...
now i got its very easy to drag and drop tree view nodes .
can i use the same for my tree view nodes coming from database ?
thanks for sharing  ...
Comment posted by Suprotim Agarwal on Wednesday, March 30, 2011 8:27 PM
Yes Ruchita, it will work with data coming from any datasource. The drag drop operation is done client side
Comment posted by Ruchita on Thursday, March 31, 2011 2:05 AM
Hi Suprotim !
ur code is working fine for static tree view items .
can u pls tell me how can i add data from my sql server data base ?
my table contain id and parentid coloumn.
parentid is the parent node in tree view .
root node will contain parent id as 0
so all child node will come under there parent id , and when i drag and drop this child id to other parent node .
it shud be update in data base table too.
pls help me .
i hav to finish this task by eod .
thanks in advance.
Comment posted by Ruchita on Friday, April 1, 2011 12:24 AM
Hi Suprotim !
I hav done my task , only the updation in db is pending.


Comment posted by Suprotim Agarwal on Saturday, April 2, 2011 6:27 AM
Good job Ruchita. I am sure you will figure out how to update the db. You need to read the serialized value and update the DB. If you google it out, there are plenty of articles written on the same.
Comment posted by Harisha on Monday, April 4, 2011 4:47 PM
Hi Suprotim
I was running in this weird issue when I tried to use the silverlight dragdragtarget with the treeview with connecting lines, here;'s the issue:
hen I try to expand the nodes clicking on the + on the nodes it is trigerring a drag even on the node , tried to cancel the drag even but am not sure if I am doing it right?

Here is the code:

<toolkit:TreeViewDragDropTarget AllowDrop="true" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" ItemDragStarting="TreeViewDragDropTarget_ItemDragStarting" ItemDragCompleted="TreeViewDragDropTarget_ItemDragCompleted" ItemDroppedOnTarget="TreeViewDragDropTarget_ItemDroppedOnTarget" Drop="TreeViewDragDropTarget_Drop">
                   <sdk:TreeView  Name="TVHierarchy" Width="Auto" Height="auto" Background="WhiteSmoke" AllowDrop="False"/>
                   </toolkit:TreeViewDragDropTarget>  

Please let me know how to handle the issue
Comment posted by Sathis on Tuesday, September 20, 2011 2:25 PM
i have seen the example of Drag and Drop Very Nice Article. Can you tell how to restrict adding inside the Child Node.It will be helpful.
Comment posted by Ganesh on Monday, February 27, 2012 3:45 AM
Great Article.
It was really useful to me.
Not only this but all of ur posts were useful to me.
Do post a lot of articles.

Thanks..