Search code examples
c#wpftreeviewdatatemplatetreeviewitem

C# WPF manage treeview item templates


Maybe this is quiet simple question but I have a problems with construction of a template for my treeview. I have some classes:

public class A //main class
{
    public B sth { get; set; }
    public C sthelse { get; set; }

    public A()
    {
        this.sth = new B(1000, "sth");
        this.sthelse = new C();
    }
}

public class B
{
    public D sth { get; set; }

    public B(ulong data, String abc)
    {
        this.sth = new D(data, abc);
    }
}

public class D
{
    public ulong data { get; private set; }
    public String abc { get; private set; }

    public D(ulong data, String abc)
    {
        this.data = data;
        this.abc = abc;
    }
}

And my question is how can I put it into treeview. I was testing HierarchicalDataTemplate but problem is that it have to be bound to collection. Any ideas how to create treeview like this:

  • A
    • B
      • D
        • data
        • abc
    • C

Is it possible?

I am using this code:

<TreeView ItemsSource="{Binding}" ItemTemplate="{StaticResource phy}" />

<Window.Resources>
        <DataTemplate x:Key="d">
            <StackPanel Orientation="Vertical">
            <!-- Maybe there should be pairs property - value, maybe grid or whatever -->
                <TextBlock Text="{Binding Path=data}" />
                <TextBlock Text="{Binding Path=abc}" />
            </StackPanel>
        </DataTemplate>
        <HierarchicalDataTemplate x:Key="b" ItemsSource="{Binding Path=sth}" ItemTemplate="{StaticResource ResourceKey=d}">
                <TextBlock Text="D" />
        </HierarchicalDataTemplate>
        <!-- Cant bind also attribute C -->
        <HierarchicalDataTemplate x:Key="phy" ItemsSource="{Binding Path=sth}" ItemTemplate="{StaticResource ResourceKey=b}">
            <TextBlock Text="PHY" />                
        </HierarchicalDataTemplate>
</Window.Resources>

In code is:

public ObservableCollection<A> data { get; private set; }

And in constructor:

data = new ObservableCollection<A>();
treeView1.DataContext = data;
data.Add(new A());

Solution

  • ItemsSource property values must be IEnumerable. There's no way to avoid this. You can expose IEnumerables in a very simple way such as below, but I would recommend a better object model than this. You can take these classes and bind the ItemsSource properties of the tree and the HierarchicalDataTemplate to this new Nodes property.

    public class A //main class
    {
        public B sth { get; set; }
        public C sthelse { get; set; }
    
        public A()
        {
            this.sth = new B(1000, "sth");
            this.sthelse = new C();
        }
    
        public IEnumerable<object> Nodes
        {
            get
            {
                yield return B;
                yield return C;
            }
        }
    }
    
    public class B
    {
        public D sth { get; set; }
    
        public B(ulong data, String abc)
        {
            this.sth = new D(data, abc);
        }
    
        public IEnumerable<object> Nodes
        {
            get
            {
                yield return D;
            }
        }
    }
    
    public class D
    {
        public ulong data { get; private set; }
        public String abc { get; private set; }
    
        public D(ulong data, String abc)
        {
            this.data = data;
            this.abc = abc;
        }
    
        public IEnumerable<object> Nodes
        {
            get
            {
                yield return data;
                yield return abc;
            }
        }
    }