Search code examples
wpftreeview

Treeview Item with children nodes of different types


I have three classes that I wish to represent in a treeview

public class ConfiguratorObjectViewModel
{
    public string Name { get; set; }
    
    public string Id { get; set; }
        
    public string ParentId { get; set; }
    
    public ObservableCollection<ConfiguratorAttributeViewModel> Attributes { get; set; } 
        
    public ObservableCollection<ConfiguratorObjectFamilyViewModel> Children { get; set; }   
}
public class ConfiguratorObjectFamilyViewModel
{
    public string Name { get; set; }
    
    public string Id { get; set; }
        
    public string ParentId { get; set; }
        
    public ObservableCollection<ConfiguratorObjectViewModel> ConfiguratorObjects { get; set; }  
}
public class ConfiguratorAttributeViewModel
{
    public string Name { get; set; }
    
    public string Id { get; set; }
        
    public string ParentId { get; set; }    
}

Here is my treeview template

<TreeView ItemsSource="{Binding RootObject}" >
    <TreeView.Resources>
    
    <HierarchicalDataTemplate DataType="{x:Type local:ConfiguratorObjectFamilyViewModel}" ItemsSource="{Binding ConfiguratorObjects}">
            <local:ConfiguratorObjectTreeItem  />
        </HierarchicalDataTemplate>
    
     <HierarchicalDataTemplate DataType="{x:Type local:ConfiguratorObjectViewModel}" ItemsSource="{Binding }" Children>
            <local:ConfiguratorObjectTreeItem  />
        </HierarchicalDataTemplate>   

    </TreeView.Resources>

</TreeView>

This template gives me all ConfiguratorObjectFamily and all ConfoguratorObject items. How do I extend this so that ConfiguratorAttribute items should be included in the tree?

I have tried extending the templates by adding combinations of the following to no avail...

<HierarchicalDataTemplate DataType="{x:Type local:ConfiguratorAttributeViewModel}" ItemsSource="{Binding Attributes}" >
    <local:ConfiguratorObjectTreeItem  />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:ConfiguratorAttributeViewModel}" >
    <local:ConfiguratorObjectTreeItem  />
</DataTemplate>

Note that the ConfiguratorAttributeViewModel is not a hierarchy


Solution

  • I found a solution by using a composite collection.

    public IList Items
    {
      get
      {
        return new CompositeCollection()
        {
          new CollectionContainer() { Collection = Children },
          new CollectionContainer() { Collection = Attributes }
        };
      }
    }
    

    And the template as such:

    <HierarchicalDataTemplate DataType="{x:Type local:ConfiguratorObjectViewModel}" ItemsSource="{Binding Items}" >
        <local:ConfiguratorObjectTreeItem  />
    </HierarchicalDataTemplate>
    
    <HierarchicalDataTemplate DataType="{x:Type local:ConfiguratorObjectFamilyViewModel}" ItemsSource="{Binding ConfiguratorObjects}">
        <local:ConfiguratorObjectTreeItem  />
    </HierarchicalDataTemplate>
    
    <DataTemplate DataType="{x:Type local:ConfiguratorAttributeViewModel}" >
        <local:ConfiguratorObjectTreeItem  />
    </DataTemplate>