In This Article

Hierarchical Data

When binding a WPF control, such as the Breadcrumb or TreeView controls, to a hierarchical data source you must specify how to locate the "child" items. This allows the WPF control to walk down the hierarchy and is typically done using the HierarchicalDataTemplate class. Although, this can also be accomplished using a Style.

Using a HierarchicalDataTemplate

The HierarchicalDataTemplate class can be used to define the look of the data and how to locate any child items. The look of the data is defined in the exact same manner as with the DataTemplate class, by specifying zero or more visual elements and binding them appropriately. The child items can be specified by setting the ItemsSource property on the HierarchicalDataTemplate class.

This sample code shows how to define a HierarchicalDataTemplate for the sample XML data below:

<HierarchicalDataTemplate ItemsSource="{Binding XPath=MyXmlElement}"
                          ...>
    <TextBlock Text="{Binding XPath=@Name}" />
</HierarchicalDataTemplate>
<?xml version="1.0" encoding="utf-8" ?>
<MyXmlElement Name="Root Item">
    <MyXmlElement Name="First Child Item">
        <MyXmlElement Name="First Grandchild Item" />
        <MyXmlElement Name="Second Grandchild Item" />
    </MyXmlElement>
    <MyXmlElement Name="Second Child Item" />
</MyXmlElement>

As you can see, the Name attribute is used by the TextBlock control to define the look. The ItemsSource property is bound to the child MyXmlElement elements, which can be used by WPF controls to find any child items.

Since hierachical data is rarely this uniform, the ItemTemplate or ItemTemplateSelector properties of the HierarchicalDataTemplate class can be used to change the template as needed.

This sample code shows how to define a HierarchicalDataTemplate for the sample XML data below, which uses distinct elements at each level:

<!-- Because this item does not have any child items we can use
     regular DataTemplate. -->
<DataTemplate x:Key="MyGrandchildXmlElementTemplate">
    <TextBlock Text="{Binding XPath=@Name}" />
</DataTemplate>

<HierarchicalDataTemplate x:Key="MyChildXmlElementTemplate"
                          ItemsSource="{Binding XPath=MyGrandchildXmlElement}"
                          ItemTemplate="{StaticResource MyGrandchildXmlElementTemplate}">
    <TextBlock Text="{Binding XPath=@Name}" />
</HierarchicalDataTemplate>

<HierarchicalDataTemplate x:Key="MyRootXmlElementTemplate"
                          ItemsSource="{Binding XPath=MyChildXmlElement}"
                          ItemTemplate="{StaticResource MyChildXmlElementTemplate}">
    <TextBlock Text="{Binding XPath=@Name}" />
</HierarchicalDataTemplate>
<?xml version="1.0" encoding="utf-8" ?>
<MyRootXmlElement Name="Root Item">
    <MyChildXmlElement Name="First Child Item">
        <MyGrandchildXmlElement Name="First Grandchild Item" />
        <MyGrandchildXmlElement Name="Second Grandchild Item" />
    </MyChildXmlElement>
    <MyChildXmlElement Name="Second Child Item" />
</MyRootXmlElement>

As you can see, we now define a HierarchicalDataTemplate for each distinct XML element and assign them appropriately as we move down the hierarchy.

Using a Style

A Style can also be used to to define the look of the data, using a DataTemplate, and how to locate any child items. This can be accomplished by setting the ItemsSource and ItemTemplate directly on the container elements, typically an ItemsControl-derived class, created for each data object. Examples of container elements include BreadcrumbItem and TreeViewItem.

This sample code shows how to define a Style for the sample XML data below:

<!-- Used to define the look -->
<DataTemplate x:Key="MyXmlElementTemplate">
    <TextBlock Text="{Binding XPath=@Name}" />
</DataTemplate>

<Style ...>
    <Setter Property="ItemsSource"
            Value="{Binding XPath=MyXmlElement}" />
    <Setter Property="ItemTemplate"
            Value="{StaticResource MyXmlElementTemplate}" />
</Style>
<?xml version="1.0" encoding="utf-8" ?>
<MyXmlElement Name="Root Item">
    <MyXmlElement Name="First Child Item">
        <MyXmlElement Name="First Grandchild Item" />
        <MyXmlElement Name="Second Grandchild Item" />
    </MyXmlElement>
    <MyXmlElement Name="Second Child Item" />
</MyXmlElement>

As you can see, the DataTemplate class defines the look just like with the HierarchicalDataTemplate class. Although, now the ItemsSource property is explictly bound to the child MyXmlElement elements using a Setter in the Style. Once the ItemsSource property is set, it can be used by WPF controls to find any child items.

This sample code shows how to define a Style for the sample XML data below, which uses distinct elements at each level:

<!-- This can be reused across all elements, because they
     all have the Name attribute -->
<DataTemplate x:Key="MyXmlElementTemplate">
    <TextBlock Text="{Binding XPath=@Name}" />
</DataTemplate>

<Style x:Key="MyGrandchildXmlElementStyle"
       ...>
       ...
</Style>

<Style x:Key="MyChildXmlElementStyle"
       ...>
    <Setter Property="ItemsSource"
            Value="{Binding XPath=MyGrandchildXmlElement}" />
    <Setter Property="ItemContainerStyle"
            Value="{StaticResource MyGrandchildXmlElementStyle}" />
    <Setter Property="ItemTemplate"
            Value="{StaticResource MyXmlElementTemplate}" />
</Style>

<Style x:Key="MyRootXmlElementStyle"
       ...>
    <Setter Property="ItemsSource"
            Value="{Binding XPath=MyChildXmlElement}" />
    <Setter Property="ItemContainerStyle"
            Value="{StaticResource MyChildXmlElementStyle}" />
    <Setter Property="ItemTemplate"
            Value="{StaticResource MyXmlElementTemplate}" />
</Style>
<?xml version="1.0" encoding="utf-8" ?>
<MyRootXmlElement Name="Root Item">
    <MyChildXmlElement Name="First Child Item">
        <MyGrandchildXmlElement Name="First Grandchild Item" />
        <MyGrandchildXmlElement Name="Second Grandchild Item" />
    </MyChildXmlElement>
    <MyChildXmlElement Name="Second Child Item" />
</MyRootXmlElement>

As you can see, we now define a Style for each distinct XML element and assign them appropriately as we move down the hierarchy.

The Breadcrumb control supports both methods of defining the data hierarchy, as does the TreeView control and others. The Breadcrumb control does differ slightly, in that the same data can be presented in more than one area of the control. For example, a data object can be displayed in a BreadcrumbItem control, a MenuItem when in a context menu, and a ComboBoxItem when display in the drop-down list.

If the data source of the Breadcrumb will be shared with another hiearchical control, then using a HierarchicalDataTemplate class would allow the look of the data to be shared. But typically, a Style is still be required to set properties not supported by the HierarchicalDataTemplate class, such as MenuItemExpandedTemplate.