Jake Varness
Jake Varness

Reputation: 63

TreeView using HierarchicalDataTemplate

I've been wrapping myself around the axle for days now.

What I'm trying to do is create a UserControl that has a TreeView in it. The TreeView is supposed to display information about a Show, and a Show has a list of Instructions in it, and so on and so forth...

I've tried to do this in various ways, but I can't get the data to show up. Here's some of my code snippets that I've tried:

<TreeView ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}, Path=DataContext.Show}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Path=Instructions}">
                    <TextBlock Text="{Binding Path=ShowName}"/>
                    <HierarchicalDataTemplate.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Path=Sounds}">
                            <TextBlock Text="{Binding Path=Name}"/>
                            <HierarchicalDataTemplate.ItemTemplate>
                                <HierarchicalDataTemplate ItemsSource="{Binding Path=Nodes}">
                                    <TextBlock Text="{Binding Path=Name}"/>
                                    <HierarchicalDataTemplate.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding Name}"/>
                                        </DataTemplate>
                                    </HierarchicalDataTemplate.ItemTemplate>
                                </HierarchicalDataTemplate>
                            </HierarchicalDataTemplate.ItemTemplate>
                        </HierarchicalDataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

And I've also tried...

<DockPanel>
        <DockPanel.Resources>
            <HierarchicalDataTemplate DataType="{x:Type show:Show}" ItemsSource="{Binding Path=Instructions}">
                <TextBlock Text="{Binding Path=ShowName}"/>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type show:Instruction}" ItemsSource="{Binding Path=Sounds}">
                <TextBlock Text="{Binding Path=Name}"/>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type show:SoundInstruction}" ItemsSource="{Binding Path=Nodes}">
                <TextBlock Text="{Binding Path=Name}"/>
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type show:NodeInstruction}">
                <TextBlock Text="{Binding Path=Name}"/>
            </DataTemplate>
        </DockPanel.Resources>
        <TreeView ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}, Path=DataContext.Show}">
        </TreeView>
    </DockPanel>

But nothing seems to work. In my MainWindow, I have this code which initializes the data context:

            Show s = new Show("Hamlet");
            s.AddInstruction(new Instruction("Inst1"));
            s.AddInstruction(new Instruction("Inst2"));
            ShowViewModel vm = new ShowViewModel(s);
            DataContext = vm;

Any help in the matter will be greatly appreciated.

Jake

Upvotes: 1

Views: 355

Answers (1)

vesan
vesan

Reputation: 3369

Your ItemsSource has to bind to something that is IEnumerable. From your code, it looks like your ShowViewModel.Show is a property that is of type Show, a single object. That will not work, you have to turn it into a collection (ObservableCollection, preferably).

The second way you used to define templates (side-by-side, not nested), is definitely nicer.

Also, assuming you don't set DataContext to anything else between your Window and DockPanel, you can change this:

<TreeView ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}, Path=DataContext.Show}">

to this:

<TreeView ItemsSource="{Binding Show}">

Your data context is automatically inherited down the visual tree.

Upvotes: 1

Related Questions