Search code examples
c#wpfxamlmvvmdatatemplate

Difference between HierachicalDataTemplate and DataTemplate with ItemsControl


I would like to know the real differences between a HierarchicalDataTemplate and a DataTemplate with an Itemcontrol within this DataTemplate.

Here is some sample code:

MainWindow.xaml

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:test="clr-namespace:WpfApplication2"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type test:TeamViewModel}">
            <TextBlock Text="{Binding Path=Name}"/>
        </DataTemplate>

        <!--<HierarchicalDataTemplate DataType="{x:Type test:TeamManagerViewModel}"
                                  ItemsSource="{Binding Path=Teams}"/>-->

        <DataTemplate DataType="{x:Type test:TeamManagerViewModel}">
            <ItemsControl ItemsSource="{Binding Path=Teams}"/>
        </DataTemplate>

    </Window.Resources>
    <Grid>
        <ContentControl Content="{Binding}"/>
    </Grid>
</Window>

ViewModel.cs

public class ViewModel : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    /// <summary>
    /// Event used by binding
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Notifies that a property has changed
    /// </summary>
    /// <param name="requestName">the property name</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion
}

TeamManagerViewModel.cs

public class TeamManagerViewModel : ViewModel
{
    private ObservableCollection<TeamViewModel> _teams;

    public TeamManagerViewModel(ObservableCollection<TeamViewModel> teams)
    {
        _teams = teams;
    }

    public ObservableCollection<TeamViewModel> Teams
    {
        get { return _teams; }
        set
        {
            _teams = value;
            OnPropertyChanged("Teams");
        }
    }
}

TeamViewModel.cs

public class TeamManagerViewModel : ViewModel
{
    private ObservableCollection<TeamViewModel> _teams;

    public TeamManagerViewModel(ObservableCollection<TeamViewModel> teams)
    {
        _teams = teams;
    }

    public ObservableCollection<TeamViewModel> Teams
    {
        get { return _teams; }
        set
        {
            _teams = value;
            OnPropertyChanged("Teams");
        }
    }
}

So the result of that is a list of the names are appearing in the window. But if I replace the DataTemplate of TeamManagerViewModel by the commented HierarchicalDataTemplate, nothing is displayed.

To me that seems quite wierd as the ItemsSourceProperty of HierarchicalDataTemplate should look for the TeamViewModel DataTemplate and use it. How is that?

And additional question what is the difference between my sample and the MSDN one (they seem to do the same as me, apart from adding a TextBlock in the HierarchicalDataTemplate)?

https://msdn.microsoft.com/fr-fr/library/system.windows.hierarchicaldatatemplate%28v=vs.110%29.aspx

Also please excuse me if I wrote my question badly, this is my first time asking something on SO.

Thanks :)


Solution

  • HierarchicalDataTemplates are used by TreeViews. From the documentation

    A TreeView can populate its tree by binding to a data source and using HierarchicalDataTemplate objects.

    ItemsControls that don't specifically show hierarchical data won't use that template. I can't off the top of my head name another control that does... Possibly Menus? Not sure. But in a TreeView use of this template type means you don't have to add a child TreeView in every template that doesn't represent a leaf. That saves some time.

    Controls that aren't designed to use them definitely won't be looking for them in your Resources.


    Because you seem so concerned about where it's actually used, I opened up JustDecompile and did a Find Usages on the type.

    The only UI type that references it directly is the HeaderedItemsControl. So any types that extend this are compatible. These include MenuItem, ToolBar, TreeViewItem, and a few WF4 designer types.

    MenuItems are used by menus, which includes ribbons and context menus. ToolBars are just that. They aren't too exciting. And TreeViewItems are used by TreeViews.

    You can do further research into the different types by grabbing a copy of JustDecompile yourself, or by browsing http://referencesource.microsoft.com/