Silverlight Toolkit – Using Silverlight TreeView Control 20

The tutorial is written for those who are very new Silverlight TreeView control. The control that I’m using in this tutorial is from Silverlight Toolkit CTP – October release.

Contents

  • Introduction
  • Getting Started with Silverlight Treeview
  • Adding the TreeViewItem from Code-behind
  • Using HierarchicalDataTemplate with TreeView
  • Model-View-ViewModel Pattern
  • Treeview with Theme
  • Known Issues

Introduction

The TreeView control provides a way to display information in a hierarchical structure. You can customize the appearance of TreeView by using DataTemplate, HierarchicalDataTemplate, Style and etc.

Sample: SilverlightTreeViewDemo.zip (724 KB)

Software Needed

  • Microsoft Visual Studio 2008
  • Silverlight 2 RTM Tool for Visual Studio 2008
  • Silverlight Toolkit CTP (Binary)

Getting Started with Silverlight Treeview

In this section, I will show you how to manually add the TreeViewItem to Treeview from XAML and code-behind file.

Let’s create new Silverlight project (I will call “SilverlightTreeViewDemo”) in VS 2008.

After creating the Silverlight project, you will need to add Microsoft.Windows.Controls.dll from Silverlight Toolkit. There are other two dlls such as Microsoft.Windows.Controls.DataVisualization.dll and Microsoft.Windows.Controls.Theming.dll and I will be convering those dlls in my upcoming tutorials.

As TreeView control is not Silverlight Core Library, you will need to add xmlns namespace in XAML like we used to do when we wanna use the custom control. I will use “control” as a prefix for Silverlight Toolkit control.

The following example shows how to create a TreeView with static TreeViewItem in XAML.  You can just copy and paste it in Page.xaml.


<control:TreeView>
<control:TreeViewItem Header="Level 1.1">
<control:TreeViewItem Header="Level 2.1">
<control:TreeViewItem Header="Level 3.1"></control:TreeViewItem>
<control:TreeViewItem Header="Level 3.2">
<control:TreeViewItem Header="Level 4.1"></control:TreeViewItem>
<control:TreeViewItem Header="Level 4.2"></control:TreeViewItem>
<control:TreeViewItem Header="Level 4.3"></control:TreeViewItem>
</control:TreeViewItem>
<control:TreeViewItem Header="Level 3.3"></control:TreeViewItem>
</control:TreeViewItem>
<control:TreeViewItem Header="Level 2.2"></control:TreeViewItem>
<control:TreeViewItem Header="Level 2.3">
<control:TreeViewItem Header="Level 3.4"></control:TreeViewItem>
<control:TreeViewItem Header="Level 3.5"></control:TreeViewItem>
<control:TreeViewItem Header="Level 3.6"></control:TreeViewItem>
</control:TreeViewItem>
<control:TreeViewItem Header="Level 2.4"></control:TreeViewItem>
</control:TreeViewItem>
<control:TreeViewItem Header="Level 1.2" />
</control:TreeView>

You will see the output below when you runs the sample.

Adding the TreeViewItem from Code-behind

If you don’t want to add those treeview items from XAML, you can also do the same thing from code-behind file. The example shows how to add a few TreeViewItem from code-behind file.


TreeViewItem tvItem = new TreeViewItem();
tvItem.Header = "Level 1.1";
tvItem.Items.Add("Level 2.1");
myTreeView.Items.Add(tvItem);
myTreeView.Items.Add("Level 1.2");
myTreeView.Items.Add("Level 1.3");

You can also do editing, removing those TreeViewItem from code-behind. As those operations are very simple, I won’t write each and everything in this post. Let’s move to HierarchicalDataTemplate which is more interesting than doing it from code-behind file or XAML.

Using HierarchicalDataTemplate with TreeView

We have learnt how to add the static TreeViewItem in XAML or in previous section. We will learn about how to use the HierarchicalDataTemplate in this section. What we did in previous section is manipulating the Treeview or TreeViewItem manually. It’s not related to the data. But we will learn how to bind the TreeView with object and we can manipulate the object without touching directly to the TreeView control.

First of all, we will create one nested class called Level in our project. And, we will add two properties called Name, Children as below in that class.


using System;
using System.Collections.Generic;

namespace SilverlightTreeViewDemo {
public class Level {
private List<Level> _children = new List<Level>();
public List<Level> Children {
get {
return _children;
}
set {
_children = value;
}
}

public string Name { get; set; }
}
}

Model-View-ViewModel Pattern

Before going to HierarchicalDataTemplat, I would like to add one interesting thing here. I know that there are a lot of people who are using Design and Pattern in their Software Development these days. MVVM (Model-View-ViewModel) pattern is the most popular pattern for UI developers. So, I’m thinking that it would be great if I use this pattern in article too. If you want to learn more about that pattern, I highly recommend you to read Nikhil’s post “Silverlight ViewModel Pattern“. He is using the attached property to communicate between View and ViewModel. But I would like to make my demo project as simple as possible so I will use the ViewModel class as a resouce in View instead of using the attached property in my sample.

As I mentioned in the screenshot above, I create new class called PageViewMoel in project and I created that viewmodel as a resource in Page.xaml. So, we are able to communicate from View to ViewModel. In other words, we are able to bind the data from ViewModel in View.

I will declare one List<Person> varible that can keep the list of Person object in ViewModel.


#region Priviate Variables
List<Level> root = new List<Level>();
#endregion

And I will populare the data to that list in the constructor of PageViewModel class. I’m going to write the code for filling data to List here but you can download the sample and check the code in your machine.

Then, you will need to export the data as a property so that you can bind that properties with TreeView in View (Page.xaml).


#region Public Methods
public List<Level> Data {
get {
return root;
}
}
#endregion

Finially, you can create the HierarchicalDataTemplate as below in XAML to display the hierachical data in TreeView. If you are using Datagrid, you can simply use the DataTemplate to customize the apperance of Datagird. The same way, you can also use Datatemplate with TreeView too but if you want to show the hierachical data then you will need to use HierarchicalDataTemplate instead of normal DataTemplate.


<control:TreeView x:Name="myTreeView" ItemsSource="{Binding Source={StaticResource model}, Path=Data}">
<control:TreeView.ItemTemplate>
<control:HierarchicalDataTemplate x:Key="PersonTemplate" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="5,0" />
</StackPanel>
</control:HierarchicalDataTemplate>
</control:TreeView.ItemTemplate>
</control:TreeView>

If you like to display other controls (e.g. Image ), you can simply put those controls inside StackPane. The following output is what I got when I add one image and one image control in HierarchicalDataTemplate that I mentioned above.

If you want to display the dynamic image, you can use ImageConverter to convert the URL to Image Bytes. Sache did a great job to create the Windows Explorer in WPF. You can also use his approach with a few changes in Silverlight too.

If you have any question or you want to get a few sample for Silverlight TreeView control, please feel free to let me know. I will try to create it for you.

Treeview with Theme

Silverlight CTP was released with six build-in themes. Those six themes are in six different assemblies. You can simply add your favoriate theme assembly as a reference in your project and then, you can easily start using it.

Let’s say you really like ExpressionDark theme and you wanna use it in your project. First thing that you need to do is that you have to create xmlns: in User Control tag as below.


xmlns:theme="clr-namespace:Microsoft.Windows.Controls.Theming;assembly=Microsoft.Windows.Controls.Theming.ExpressionDark"

And then, you have to put all of your controls inside the theme controls (e.g. <theme:ExpressionDarkTheme>). That’s all. The look and feel of all of your controls will be changed on the theme that you applied.


<theme:ExpressionDarkTheme>
<control:TreeView x:Name="myTreeView" ItemsSource="{Binding Source={StaticResource model}, Path=Data}"
Width="300">
<control:TreeView.ItemTemplate>
<control:HierarchicalDataTemplate x:Key="PersonTemplate" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="5,0" />
</StackPanel>
</control:HierarchicalDataTemplate>
</control:TreeView.ItemTemplate>
</control:TreeView>
</theme:ExpressionDarkTheme>

Known Issues

1. DisplayMemberPath in TreeView is not working.

2. Nested HierarchicalDataTemplate: You can’t use the nested HierarchicalDataTemplate with Silverlight TreeView control.

For example:You will get the error if you are using the nested HierarchicalDataTemplate as below.


<UserControl x:Class="
<div dir="ltr">SilverlightApplication1.Page"
xmlns="<a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation" target="_blank">http://schemas.microsoft.com/winfx/2006/xaml/presentation</a>"
xmlns:x="<a href="http://schemas.microsoft.com/winfx/2006/xaml" target="_blank">http://schemas.microsoft.com/winfx/2006/xaml</a>"
xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<toolkit:TreeView x:Name="familyTreeView">
<toolkit:TreeView.ItemTemplate>
<toolkit:HierarchicalDataTemplate ItemsSource="{Binding Path=Children}">
<TextBlock Text="{Binding Path=Name}"/>
<toolkit:HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}"/>
</DataTemplate>
</toolkit:HierarchicalDataTemplate.ItemTemplate>
</toolkit:HierarchicalDataTemplate>
</toolkit:TreeView.ItemTemplate>
</toolkit:TreeView>
</Grid>
</UserControl></div>
<div dir="ltr"></div>
<div dir="ltr">
If you encounter any issue with this control, please drop a comment. I will add this to this list so that it would be helpful for other people.

20 thoughts on “Silverlight Toolkit – Using Silverlight TreeView Control

  1. Pingback: 2008 October 29 - Links for today « My (almost) Daily Links

  2. Reply Phil Salomon Oct 29,2008 4:23 am

    I’m not getting the little triangles for some reason. Any ideas.

    void AddNodes(System.Collections.IList c1, MSAServiceReference.Category[] l, string Parent)
    {
    TreeViewItem TreeItem;

    foreach (MSAServiceReference.Category c in l)
    {
    if (Parent == c.CatParent)
    {
    TreeItem = new TreeViewItem();
    TreeItem.Header = c.CatDescription;
    TreeItem.Tag = c.CategoryNo;
    c1.Add(TreeItem);
    AddNodes(TreeItem.Items, l, c.CategoryNo);
    }
    }
    }

    void proxy_GetCategoriesCompleted(object sender, MicronetOnlineOrdering.MSAServiceReference.GetCategoriesCompletedEventArgs e)
    {
    MSAServiceReference.Category[] l;

    if (e.Error != null)
    {
    string err = e.Error.ToString();
    return;
    }

    l = e.Result;
    AddNodes(catTree.Items, l, “”);

    catTree.Width = this.treeGrid.ColumnDefinitions[0].ActualWidth;
    catTree.Height = this.treeGrid.RowDefinitions[0].ActualHeight;
    }

  3. Reply Ravindra Oct 30,2008 6:04 am

    some of the developed Themes are not working.

  4. Reply Jerry Evans Oct 31,2008 12:12 pm

    Hi Michael

    Nice. But I can’t run this using SL2 RTW + the latest drop of the Silverlight Toolkit.

    Expression Blend SP1 complains about
    control:HierarchicalDataTemplate with an error of ‘The key attribute can only be used on an element that is contained in IDictionary’.

    Any thoughts?

  5. Pingback: Shawn Burke's Blog : A Ridiculous List of Silverlight Toolkit Resources

  6. Reply Mark McPherson Dec 4,2008 12:22 pm

    My data is retrieved from ADO.NET Data Services which means the TreeView nodes must be created after the data has been retrieved. In code I set the ItemsSource for the TreeView but nothing is displayed. I am using the HierarchicalDataTemplate as outlined in your sample. In the debugger I can see that 60+ records (class instances) are in the ItemsSource.

    What am I missing. This pattern of setting the ItemsSource after the async call finishes works great for the DataGrid.

    Thanks,
    Mark

  7. Reply Abhishek vashistha Dec 15,2008 10:48 pm

    Hi Michael,
    I am not able to use themes as you have used(ExpressionDarkTheme).
    I am getting AG_E_PARSER_BAD_TYPE when components are being initialized.

    Please suggest

  8. Reply Arch Dec 19,2008 7:24 am

    Good article. The problem with this approach in any non-trivial application is that you would not load your entire tree hierarchy up front. How would you implement lazy loading of child nodes?

    I’ve seen solutions that use the Item_Expanded event to load the child nodes. But it’s usually done by iterating thru your (strongly-typed) collection and converting each member to TreeViewItems before adding to tree. This negates the advantages of binding your objects to the tree and breaks mv-vm capability.

    Any good solution to this?

  9. Reply Kellen Sunderland Apr 7,2009 8:59 am

    I would love to see some events to hook into with tree view for drag and drop. Displaying hierarchical data is good but editing it would be better.

  10. Reply thaianhduc Jun 4,2009 3:11 am

    I am using SilverLight 3 and cannot find the HierarchicalDataTemplate control. Any idea?
    In fact i cannot find the Microsoft.Windows.Controls.dll even though i have installed toolkit 3.

  11. Reply j h Jun 10,2009 8:24 am

    Get HierarchicalDataTemplate from System.Windows.Controls.Toolkit rather than the older Microsoft.Windows.Controls.dll

  12. Reply sir fidel Jun 12,2009 2:01 pm

    I am trying to create treeview control in silverlight and tried to follow your demo but i am not able too…how can i create treeview with the toolkit march

    how can i create treeview with THE MARCH RELEASE

  13. Reply Atul Katare Jul 27,2009 3:06 am

    Hi

    I want add node at run time.
    Is it possible using your example?
    Thank You

  14. Reply b.dhanapal Aug 11,2009 1:37 am

    hi,

    I need to populate the silverlight treeview dynamically using sqlserver database and asp.net

    thank you

  15. Reply Jules Sep 27,2009 8:17 am

    I enclosed my Tree View control, but couldnt get past the folloiwhg catastorpic error in the Visual Designer.

    Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
    at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
    at MS.Internal.XcpImports.RenderTargetBitmapRender(HostingRenderTargetBitmap bitmap, UIElement visual, Int32& dirtyX, Int32& dirtyY, Int32& dirtyWidth, Int32& dirtyHeight)
    at System.Windows.Interop.HostingRenderTargetBitmap.Render(UIElement visual)
    at MS.Internal.Silverlight.Host.RuntimeInterop.RenderElementToTargetBitmap(Int32 elementKey, Int32 targetBitmapIdentifier)
    at MS.Internal.Silverlight.Host.Interop.RenderElementToTargetBitmap(Int32 element, Int32 targetBitmapIdentifier, ISilverlightContentDownloadCallback urlcallback)
    at MS.Internal.Silverlight.Host.CiderSilverlightImageHost.CiderInternalImage.UpdateBitmap()
    at MS.Internal.Silverlight.Host.CiderSilverlightImageHost.CiderInternalImage.UpdateTree()
    at MS.Internal.Silverlight.Host.CiderSilverlightImageHost.CiderInternalImage.MeasureOverride(Size constraint)
    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
    at System.Windows.UIElement.Measure(Size availableSize)
    at MS.Internal.Silverlight.Host.CiderSilverlightImageHost.MeasureOverride(Size constraint)
    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
    at System.Windows.UIElement.Measure(Size availableSize)
    at System.Windows.ContextLayoutManager.UpdateLayout()
    at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
    at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
    at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
    at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
    at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

  16. Reply Les Fergsuon Feb 16,2010 3:26 pm

    With VS2008, Silverlight 3 toolkit Nov 2009;

    Where you say “you will need to add xmlns namespace in XAML like we used to do when we wanna use the custom control” your image shows a popup completion list to select the Microsoft.Windows.Controls assembly from.
    Any idea why I cannot get this completion list to appear?

  17. Reply Reynaldo Ruiz May 18,2010 9:18 am

    Thanks Mike just what I was looking for…

  18. Reply Virtual Office Apr 20,2011 7:48 am

    I had a silverlight tool kit but not with the silverlight treeview tool..hmmm..I might download this one.

  19. Reply shwetank Jul 1,2011 3:22 am

    how do u add image in tree control can bit elaborate as u have mentioned in above tree.

  20. Reply shwetank Jul 7,2011 11:38 pm

    how do u place image to TreeViewItem in tree control?
    can we place it in .xaml code behoind?

Leave a Reply