0

I have a TreeView which is bound to CompositeCollection made of MyItem and MyGroup objects.

Class definitions:

public class MyItem
{
    public string Name { get; set; }

    public MyItem(string name = "")
    {
        Name = name;
    }
}


public class MyGroup
{
    public string Name { get; set; }
    public List<MyGroup> MyGroups = new List<MyGroup>();
    public List<MyItem> MyItems = new List<MyItem>();

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

    public MyGroup(string name)
    {
        Name = name;
    }
}

XAML:

<TreeView Name="myTreeView">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:MyGroup}" ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type local:MyItem}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

Code for setting up the tree:

var root = new ObservableCollection<MyGroup>();
myTreeView.ItemsSource = root;

MyGroup g1 = new MyGroup("First");
MyGroup g2 = new MyGroup("Second");
MyGroup g3 = new MyGroup("Third");
MyItem i1 = new MyItem("Item1");
MyItem i2 = new MyItem("Item2");
MyItem i3 = new MyItem("Item3");

root.Add(g1);
root.Add(g2);
g2.MyGroups.Add(g3);
g1.MyItems.Add(i1);

The problem is whenever I run the code, only First and Second are displayed, but the expand arrow is not present next to Second, and it can't be expanded. Debugging shows the g2 has g3 as child, but it is not present in the TreeView control.

How can I fix it? The aim is to do it with as little code as possible, I try to avoid adding loads of abstraction layers and wrapper classes...

Went through these, didn't solve my problem:

Community
  • 1
  • 1
Adam Szabo
  • 11,302
  • 18
  • 64
  • 100

1 Answers1

1

I was able to solve the problem with the following modifications in the source code:

Class MyGroup:

public class MyGroup
{
    public string Name { get; set; }

    private IList children = new CompositeCollection() {
                new CollectionContainer { Collection = new List<MyGroup>() },
                new CollectionContainer { Collection = new List<TestItem>() }
    };

    public IList Children
    {
        get { return children; }
        set { children = value; }
    }

    public MyGroup(string name)
    {
        Name = name;
    }
}

Code for setting up the tree:

var root = new ObservableCollection<MyGroup>();
myTreeView.ItemsSource = root;

MyGroup g1 = new MyGroup("First");
MyGroup g2 = new MyGroup("Second");
MyGroup g3 = new MyGroup("Third");
MyItem i1 = new MyItem("Item1");
MyItem i2 = new MyItem("Item2");
MyItem i3 = new MyItem("Item3");

root.Add(g1);
root.Add(g2);
g2.Children.Add(g3);
g1.Children.Add(i1);

So despite of what is suggested at WPF Treeview Databinding Hierarchal Data with mixed types, I had to get rid of the two separate lists in MyGroup (which standed for different types of objects), and use only one CompositeCollection, and then add the child items to the Children list, regardless of the type of the child object.

Community
  • 1
  • 1
Adam Szabo
  • 11,302
  • 18
  • 64
  • 100