0

C# / WPF. I am trying to display my object model in a TreeView, with data bound using <HierarchicalDataTemplate>. I am basing my method on this description.

I have created an object hierarchy for testing purposes. The code runs, but the tree view only displays the top-level item (in this case the house address). I have not been able to get it to display any sub nodes. I understand that the top-level object has to be an ObservableCollection so I create one for the purposes of the TreeView.

What am I doing wrong here?

public class House {
    public string Address { get; set; } = "Baker Street";
    public List<Dog> dog = new List<Dog>() { new Dog() };
}
public class Dog {
    public string Name { get; set; } = "Rover";
    public List<Claw> claw = new List<Claw>() { new Claw() };
    public List<Whisker> whisker = new List<Whisker>() { new Whisker() };
    public Tail tail = new Tail();
    public Dog() { }
}
public class Claw {
    public float length { get; set; } = 0;
    public Claw() { }
}
public class Whisker {
    public float length { get; set; } = 0;
    public Whisker() { }
}
public class Tail
{
    public float length { get; set; } = 0;
    public Tail() { }
}

ObservableCollection<House> _house = new ObservableCollection<House>(){ new House() };
treeViewConfig2.ItemsSource = _house;

<StackPanel>
    <StackPanel.Resources>

        <DataTemplate x:Key="TailTemplate">
            <TextBlock Text="{Binding Length}" Foreground="Green" />
        </DataTemplate>

        <HierarchicalDataTemplate x:Key="DogTemplate"
            ItemsSource="{Binding Tail}"
            ItemTemplate="{StaticResource TailTemplate}">
            <TextBlock Text="{Binding Name}" Foreground="Red" />
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate x:Key="HouseTemplate"
            ItemsSource="{Binding Dog}"
            ItemTemplate="{StaticResource DogTemplate}">
            <TextBlock Text="{Binding Address}" />
        </HierarchicalDataTemplate>

    </StackPanel.Resources>
    <TreeView Name ="treeViewConfig2" ItemsSource="{Binding}" ItemTemplate="{StaticResource HouseTemplate}"/>

</StackPanel>
wotnot
  • 261
  • 1
  • 12
  • additionally names in viewmodel and binding must be the same, casing is important. `Tail` and `tail` are not the same – ASh Jun 11 '20 at 07:12
  • 1
    There's mistake with property name `Binding` "dog" != "Dog", "tail" != "Tail", etc. And additionally `treeViewConfig2.ItemsSource = _house;` conflicts with `ItemsSource="{Binding}"` – aepot Jun 11 '20 at 07:17
  • Understood, thanks. I wasn't sure whether ItemsSource was supposed to contain the instance name or the class name. Seems it should be the former. However, I have tried both. I have now got `ItemsSource="{Binding dog}"` and `ItemsSource="{Binding tail}"` and have removed `ItemsSource="{Binding}"` from the TreeView definition to remove the conflict. Behaviour is still the same. – wotnot Jun 11 '20 at 07:28
  • I don't understand why this has been closed as a duplicate. The other post is about why binding does not work with fields, as opposed to properties. I don't think I have got any fields(?). – wotnot Jun 11 '20 at 07:34
  • 1
    "I don't think I have got any fields" - you are very much mistaken. `public List dog ` is a field - no getter/setter – ASh Jun 11 '20 at 09:29
  • I see. Thanks. I guess that is probably the problem. – wotnot Jun 11 '20 at 09:46
  • That was largely the problem. I have added getters and setters to the object lists and now I see the second level in the TreeView. No third level, however. Rover has no tail. I cannot see the reason for this. (I have corrected the lower case 'l' in the 'length' property, which is now 'Length'.) – wotnot Jun 11 '20 at 10:37

0 Answers0