0
votes

I have following problem with which I'm wrestling now for about 5 hours.

How do I correctly bind the following class structure to a TreeView?

public class Person
{
    public string Display { get; set; }
    public List<Car> Cars { get; set; }
    public List<House> Houses { get; set; }
}

public class Car
{
    public string Display { get; set; }
}

public class House
{
    public string Display { get; set; }
}

I want the TreeView to have the following structure: (Where Person #1 has both houses and cars, and Person #2 just has houses)

- Person #1
|-- Cars
  |-- Car #1
  |-- Car #2
|-- Houses
  |-- House #1
- Person #2
|-- Houses
  |-- House #1
  |-- House #2

How on earth do you this in XAML with automatic Databinding to an ObservableCollection? I set the binding only once in the Constructor of my Treeview (UserControl) like this:

this.ItemsSource = SomeStaticClass.People;

Help is very very much appreciated! Thanks! =)

EDIT: I tried the HierarchicalDataTemplate, but I can't get it to work ;)

EDIT2: I tried many many different things, but the closest I have come to is following code (with just one Enumeration in mind at this time ;)):

<HierarchicalDataTemplate DataType="{x:Type e:Person}" ItemsSource="{Binding Cars}">
    <TextBlock Text="{Binding Display}" />
    <HierarchicalDataTemplate.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Cars}">
            <TextBlock Text="Cars" />
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Display}" />
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>

Unfortunately, it doesn't display the TextBlock Cars and the Cars themself. How do I do that?

1
Yes, I have tried everything with this template. It won't work, it doesn't matter what I try. :)Shion
See Edit2 For my editet answer which shows my code so far. Thanks!Shion

1 Answers

0
votes

Finally solved. I just inserted another Collection of classes between my Person and Car (resp. Home) like this:

public class CollectionHolder<T> : IEnumerable
{
    public List<T> Items { get; set; }
    public string Display { get; set; }

    private List<CollectionHolder<T>> self;
    public CollectionHolder()
    {
        self = new List<CollectionHolder<T>>();
        self.add(this);
    }

    public IEnumerator GetEnumerator()
    {
        return self.GetEnumerator();
    }
}

And than the Person class:

public class Person
{
    public string Display { get; set; }
    public CollectionHolder<Car> Cars { get; set; }
    public CollectionHolder<House> Houses { get; set; }

    public IList Children
    {
        get
        {
            return new CompositeCollection
                {
                    new CollectionContainer { Collection = Cars },
                    new CollectionContainer { Collection = Houses }
                });//In real world: don't generate the list everytime!
        }
    }
}

And finally my XAML:

    <TreeView x:Name="trvData" Grid.Row="0" BorderThickness="0,0,0,1">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type e:Person}" ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Display}" />
                <HierarchicalDataTemplate.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Items}">
                        <TextBlock Text="{Binding Display}" />
                        <HierarchicalDataTemplate.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Display}" />
                            </DataTemplate>
                        </HierarchicalDataTemplate.ItemTemplate>
                    </HierarchicalDataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>