Mauro Sampietro
Mauro Sampietro

Reputation: 2814

Wpf Treeview grouping

I have a TreeView bound to a List<MyCustomType>. I need to display the list grouped by MyType.MyGroupingProperty and show the list items themselves as leaves. How can i do that?

What i tried

Since I need to display the list grouped by MyType.MyGroupingProperty, I create a CollectionViewSource, bind it to TreeView and create HierarchicalDataTemplate:

<CollectionViewSource x:Key="cvs" Source="{Binding}">
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="MyGroupingProperty"/>
    </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

 <HierarchicalDataTemplate  DataType="{x:Type vm:DeviceViewModel}" ItemsSource="{Binding Items}" >
     <TextBlock Text="{Binding MyGroupingProperty}" />
 </HierarchicalDataTemplate>

So far, so good. But now i can't display items cause DataTemplate need a type i already used and i get an exception 'key already added to dictionary'; if i use a x:key it does not work either.

 <DataTemplate DataType="{x:Type vm:DeviceViewModel} >
      <TextBlock Text="{Binding AnotherProperty}" />
 </DataTemplate>

Upvotes: 3

Views: 3503

Answers (1)

Nadia Chibrikova
Nadia Chibrikova

Reputation: 5036

As you're binding your TreeView to groups, HierarchicalDataTemplate will deal with them and not with DeviceViewModel, so the template should be something like

<HierarchicalDataTemplate ItemsSource="{Binding Path=Items}"  ItemTemplate="{StaticResource dataTemplate}">
      <TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>

The complete solution will look like this:

    <TreeView ItemsSource="{Binding Source={StaticResource yourCollection}, Path=Groups}" >
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Items}">
                <!--GroupItem.Name-->
                <TextBlock Text="{Binding Path=Name}" />
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                         <!--your item's property-->
                        <TextBlock Text="{Binding Path=Property}"/>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

Hope it helps.

P.S. I didn't know you needed the templates to be in resources, but it's possible of couse. As I haven't seen your code I can only guess what's wrong, but I suspect you specify the wrong target type, try this:

 <TreeView.Resources>
            <HierarchicalDataTemplate ItemsSource="{Binding Items}" DataType="{x:Type CollectionViewGroup}">

The rest is the same. If the template's type is different from the real one it will use the default way of presenting data (text blocks + ToString()).

Upvotes: 3

Related Questions