How to: Use a TreeView to Display Hierarchical Data

Microsoft Silverlight will reach end of support after October 2021. Learn more.

The TreeView and TreeViewItem controls can be used with HierarchicalDataTemplate objects to easily display hierarchical data. This topic describes how to create the templates and create the TreeView structure. The code examples in this topic require a reference to the System.Windows.Controls assembly and the following namespace mapping.

xmlns:sdk="https://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"

To create the templates

  • Declare the templates in ascending order. Set the HierarchicalDataTemplate.ItemsSource property to the data source for the sub-nodes and set the HierarchicalDataTemplate.ItemTemplate property to a template that defines the structure for those nodes. The following example shows two HierarchicalDataTemplate resources. The first template applies to the lowest nodes in the tree and the second template applies to the items that contains those nodes.

    <StackPanel.Resources>
        <sdk:HierarchicalDataTemplate x:Key="ChildTemplate" >
           <TextBlock FontStyle="Italic" Text="{Binding Path=Title}" />
         </sdk:HierarchicalDataTemplate>
        <sdk:HierarchicalDataTemplate x:Key="NameTemplate" 
            ItemsSource="{Binding Path=ChildTopics}" 
            ItemTemplate="{StaticResource ChildTemplate}">
            <TextBlock Text="{Binding Path=Title}" FontWeight="Bold" />
            </sdk:HierarchicalDataTemplate>
    </StackPanel.Resources>
    

To create the TreeView structure

  • Create a TreeView and set its ItemsControl.ItemTemplate property to the highest-level data template. Typically the highest-level data template is the last one declared if the templates are declared as resources.

    <sdk:TreeView Width="400"  Height="300" ItemsSource="{Binding}" 
        ItemTemplate="{StaticResource NameTemplate}" x:Name="myTreeView" />
    

Example

The following example shows two hierarchical data templates declared in ascending order. The example shows a TreeView with its ItemsControl.ItemTemplate set to the template that applies to the highest-level nodes.

Run this sample

Partial Public Class MainPage
    Inherits UserControl
    Public Shared Topics As New ObservableCollection(Of Topic)()
    Public Sub New()
        InitializeComponent()

        Topics.Add(New Topic("Using Controls and Dialog Boxes", -1))
        Topics.Add(New Topic("Getting Started with Controls", 1))
        Dim DataGridTopic As New Topic("DataGrid", 4)
    DataGridTopic.ChildTopics.Add( _
            New Topic("Default Keyboard and Mouse Behavior in the DataGrid Control", -1))
    DataGridTopic.ChildTopics.Add( _
        New Topic("How to: Add a DataGrid Control to a Page", -1))
    DataGridTopic.ChildTopics.Add( _
        New Topic("How to: Display and Configure Row Details in the DataGrid Control", 1))
        Topics.Add(DataGridTopic)
        myTreeView.DataContext = Topics
End Sub
End Class

Public Class Topic
    Private _Title As String
    Public Property Title() As String
        Get
            Return _Title
        End Get
        Set(ByVal value As String)
            _Title = value
        End Set
    End Property
    Private _Rating As Integer
    Public Property Rating() As Integer
        Get
            Return _Rating
        End Get
        Set(ByVal value As Integer)
            _Rating = value
        End Set
    End Property
    Private childTopicsValue As New ObservableCollection(Of Topic)()
    Public Property ChildTopics() As ObservableCollection(Of Topic)
        Get
            Return childTopicsValue
        End Get
        Set(ByVal value As ObservableCollection(Of Topic))
            childTopicsValue = value
        End Set
    End Property
    Public Sub New()
    End Sub
    Public Sub New(ByVal title__1 As String, ByVal rating__2 As Integer)
        Title = title__1
        Rating = rating__2
    End Sub
End Class
public partial class MainPage : UserControl
{
    static public ObservableCollection<Topic> Topics = new ObservableCollection<Topic>();
    public MainPage()
    {
        InitializeComponent();

        Topics.Add(new Topic("Using Controls and Dialog Boxes", -1));
        Topics.Add(new Topic("Getting Started with Controls", 1));
        Topic DataGridTopic = new Topic("DataGrid", 4);
        DataGridTopic.ChildTopics.Add(
            new Topic("Default Keyboard and Mouse Behavior in the DataGrid Control", -1));
        DataGridTopic.ChildTopics.Add(
            new Topic("How to: Add a DataGrid Control to a Page", -1));
        DataGridTopic.ChildTopics.Add(
            new Topic("How to: Display and Configure Row Details in the DataGrid Control", 1));
        Topics.Add(DataGridTopic);
        myTreeView.DataContext = Topics;
    }
}

public class Topic
{
    public string Title { get; set; }
    public int Rating { get; set; }
    private ObservableCollection<Topic> childTopicsValue = new ObservableCollection<Topic>();
    public ObservableCollection<Topic> ChildTopics {
        get
        {
            return childTopicsValue;
        }
        set
        {
            childTopicsValue = value;
        }
    }
    public Topic() {}
    public Topic(string title, int rating)
    {
       Title = title;
       Rating = rating;
    }
}
<StackPanel x:Name="LayoutRoot" Background="White">
    <StackPanel.Resources>
        <sdk:HierarchicalDataTemplate x:Key="ChildTemplate" >
           <TextBlock FontStyle="Italic" Text="{Binding Path=Title}" />
         </sdk:HierarchicalDataTemplate>
        <sdk:HierarchicalDataTemplate x:Key="NameTemplate" 
            ItemsSource="{Binding Path=ChildTopics}" 
            ItemTemplate="{StaticResource ChildTemplate}">
            <TextBlock Text="{Binding Path=Title}" FontWeight="Bold" />
            </sdk:HierarchicalDataTemplate>
    </StackPanel.Resources>
    <sdk:TreeView Width="400"  Height="300" ItemsSource="{Binding}" 
        ItemTemplate="{StaticResource NameTemplate}" x:Name="myTreeView" />
  </StackPanel>