0
votes

most of the found (so far) articles about using WPF with MVVM pattern, describe binding TreeView to tree of same elements, e.g. http://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode.

in those tutorials, there is only a single class, which contains children of the same type, such as class "person" which has parents and children. TreeView uses HierarchicalDataTemplate, to bind to a single class.

what if there are a selection of different classes, which build a tree. as an example consider such xml:

<a x=1>
    <b x=2>
        <c x=3 />
        <c x=3 />
    </b>
</a>

so each xml element is wrapped into a different class: classes A, B and C.

how to properly write XAML to bind those?

in order to show first 2 layers below XAML is suited:

<TreeView ItemsSource="{Binding As}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Bs}">
             <TreeViewItem>
                 <TreeViewItem.Header>
                    <TextBlock Text="{Binding x}" />
                 </TreeViewItem.Header>
             </TreeViewItem>
         </HierarchicalDataTemplate>
     </TreeView.ItemTemplate>
  </TreeView>

but how to include 3rd layer, namely C?

2

2 Answers

0
votes

When displaying different data types in a single collection in WPF, we define what each type should look like using DataTemplates. But we can only apply one DataTemplate I hear you shout... not if we don't specify an x:Key value, we don't. So, the solution is simple... define a DataTemplate for each data type and just don't set the x:Key value on any of them - in this way, the Framework will implicitly apply them to the individual items.

<DataTemplate DataType="{x:Type SomePrefix:SomeType}">
    ...
</DataTemplate>

...

<DataTemplate DataType="{x:Type SomePrefix:AnotherType}">
    ...
</DataTemplate>

The final part of the solution is to ensure that all your data types extend a base class that you need to create:

public class SomeType : BaseDataType { ... }

...

public class AnotherType: BaseDataType { ... }

Now you can data bind a collection of this BaseDataType type to your TreeView and fill it with any class that extends the base class:

public ObservableCollection<BaseDataType> Items { get; set; }

...

Items.Add(new SomeType());
Items.Add(new AnotherType());

...

<TreeView ItemsSource="{Binding Items}" ... />
0
votes

the solution is to include HierarchicalDataTemplates hierarchically, as described in http://blogs.msdn.com/b/mikehillberg/archive/2009/10/30/treeview-and-hierarchicaldatatemplate-step-by-step.aspx.