olhptr
olhptr

Reputation: 87

Multiple HierarchicalDataTemplate

I have some trouble with TreeView in WPF. I have got three collection which contains each other. So, i have got a Group type, in it there is a MasterActions ObservableCollection. In MasterAction there is a SlaveActions ObservableCollection. Group, MasterAction and SlaveAction classes have a Description property. I would like to bind them to a TreeView. I tried HierarchicalDataTemplate construction, but it is not working.

There is the Xaml code:

<TreeView x:Name="TreeViewResult" HorizontalAlignment="Stretch" ItemsSource="{Binding}" VerticalAlignment="Stretch"  Margin="10,10,10,10" >
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Groups}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Margin="3" Text="{Binding Description}"/>
            </StackPanel>
            <HierarchicalDataTemplate.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding MasterActions}">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Description}"/>
                    </StackPanel>
                    <HierarchicalDataTemplate.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding SlaveActions}">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Description}"/>
                            </StackPanel>
                        </HierarchicalDataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

Codebehind:

Handler handler = new Handler();
Group group1 = new Group("group1_description");
MasterAction masterAction11 = new MasterAction("masterAction11");
SlaveAction slaveAction111 = new SlaveAction("slaveAction111");
SlaveAction slaveAction112 = new SlaveAction("slaveAction112");
MasterAction masterAction12 = new MasterAction("masterAction12");
MasterAction masterAction13 = new MasterAction("masterAction13");
SlaveAction slaveAction131 = new SlaveAction("slaveAction131");
handler.Add(group1);
handler.Add(masterAction11);
handler.Add(slaveAction111);
handler.Add(slaveAction112);
handler.Add(masterAction12);
handler.Add(masterAction13);
handler.Add(slaveAction131);
Group group2 = new Group("group2_description");
MasterAction masterAction21 = new MasterAction("masterAction21");
MasterAction masterAction22 = new MasterAction("masterAction22");
SlaveAction slaveAction221 = new SlaveAction("slaveAction221");
SlaveAction slaveAction222 = new SlaveAction("slaveAction222");
SlaveAction slaveAction223 = new SlaveAction("slaveAction223");
SlaveAction slaveAction224 = new SlaveAction("slaveAction224");
handler.Add(group2);
handler.Add(masterAction21);
handler.Add(masterAction22);
handler.Add(slaveAction221);
handler.Add(slaveAction222);
handler.Add(slaveAction224);
TreeViewResult.ItemsSource = handler.Groups;

Handler.Add() is an overloaded method. It manages all of three parameter to construct tree.

group1_description
    masterAction11
        slaveAction111
        slaveAction112
    masterAction12
    masterAction13
        slaveAction131
group2_description
    masterAction21
    masterAction22
        slaveAction221
        slaveAction222
        slaveAction223
        slaveAction224

When i run the code, it produces the next:

enter image description here

How can i reach to appear all MasterActions and SlaveActions description under the right node?

Thanks in advance.

Upvotes: 2

Views: 6437

Answers (1)

dkozl
dkozl

Reputation: 33364

It looks as if you try to go one level too deep with your HierarchicalDataTemplate. You set ItemsSource in your code to Groups

TreeViewResult.ItemsSource = handler.Groups;

and it actually does not matter how you set it (in code or via binding) more important is that top level item is a Group and you bind top level HierarchicalDataTemplate.ItemsSource to Groups. Instead of that move everything one level up and bind top level ItemsSource to MasterActions, next level to SlaveActions and lowest level can then be simple DataTemplate that would display Description without child nodes

<TreeView 
    x:Name="TreeViewResult" 
    HorizontalAlignment="Stretch" 
    VerticalAlignment="Stretch"
    Margin="10,10,10,10" >
    <!-- top node will be a Group -->
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding MasterActions}">
            <TextBlock Margin="3" Text="{Binding Description}"/>
            <!-- child node will be a MasterAction -->
            <HierarchicalDataTemplate.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding SlaveActions}">
                    <TextBlock Text="{Binding Description}"/>
                    <!-- leaf will be a SlaveAction -->
                    <HierarchicalDataTemplate.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Description}"/>
                        </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

also, not related to your problem, but since you display single TextBlock you don't need StackPanel

Upvotes: 3

Related Questions