Home > Software design >  Binding Composite Object to Tree View WPF
Binding Composite Object to Tree View WPF

Time:11-05

I have an object that follows Composite design pattern. I would like to show this object in a WPF using tree view but I have trouble binding the data correctly. I have two classes: Leaf, simple class that doesnt have any children, and Box, compound class that has children elements which could be both of Leaf class of Box class. I also have a common interface called ITree

Interface

public interface ITree
{
  string Name { get; }
  string Property1 { get; }
  string Property2 { get; } 
}

Simple class

public class Leaf : ITree
{
  string ITree.Name { get { return _name; } }
  string ITree.Property1 { get { return property1; } }
  string ITree.Property2 { get { return property2; } }
}

Compound class

public class Box : ITree
{
  string ITree.Name { get { return _name; } }
  string ITree.Property1 { get { return property1; } }
  string ITree.Property2 { get { return property2; } }
  List<ITree> Children = new List<ITree>();
}

xaml.cs

List<ITree> ListToBind = new List<ITree>();
ITree finalObject = PopulateCompositeObjeectWithData();
ListToBind.Add(finalObject);

xaml

<TreeView ItemsSource="{Binding ElementName=Window, Path= ListToBind}">
   <TreeView.ItemTemplate>
      <HierarchicalDataTemplate ItemsSource="{Binding Children}">
           <TextBlock Text="{Binding Name}"/>
       </HierarchicalDataTemplate>
   </TreeView.ItemTemplate>
</TreeView>

The tree view I am trying to achieve:

Box - Name
  |-Leaf - Name
  |-Leaf - Name
  |-Box - Name
  |  |-Leaf - Name
  |  |-Leaf - Name

Any suggestion or code samples would be greatly appreciated

Thank you

CodePudding user response:

First of all, Children must be public property for you to be able to bind to it:

public class Box : ITree
{
    string ITree.Name { get { return _name; } }
    string ITree.Property1 { get { return property1; } }
    string ITree.Property2 { get { return property2; } }
    public List<ITree> Children { get; } = new List<ITree>();
}

Second, you should bind to explicit implemented interface members using parentheses like this:

<TreeView ItemsSource="{Binding ElementName=Window, Path= ListToBind}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding (local:ITree.Name)}"/>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>
  • Related