How do I set a DataTemplate for a WPF TreeView to display all Elements of an List?

17,801

Solution 1

I used the page Mateusz mentioned (HierarchicalDataTemplate) and after reading the answer to this question: Bind Collection to StackPanel I found a solution that did what I wanted:

Here the players (level 3) are on the same row as the team (level 2):

<TreeView ItemsSource="{Binding League}">
    <!-- Conference template -->
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Teams}">
            <TextBlock Foreground="Red" Text="{Binding Name}" />
            <!-- Team template -->
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}"/>
                        <ItemsControl ItemsSource="{Binding Players}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel Orientation="Horizontal">
                                    </StackPanel>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Button Content="{Binding }"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

the result

Solution 2

Please try to use HierarchicalDataTemplate with TreeView.

HierarchicalDataTemplate

Share:
17,801
Onur
Author by

Onur

Updated on June 14, 2022

Comments

  • Onur
    Onur almost 2 years

    I'd like to visualize the following data structure using TreeViews in WPF:

    class MyDataContext
    {
        ICollectionView Outers {get;set;}
        //...
    }
    
    class Outer
    {
        string Name {get;set;}
        IEnumberable<Inner> Actions {get;set;} 
    }
    
    
    class Inner
    {
        string Description {get;set;}
        Command OnClick {get;set;}
    }
    

    This is my attempt so far:

    <!-- DataContext is MyDataContext at this  point -->
    <TreeView ItemsSource="{Binding Path=Outers}">
        <TreeView.Resources>
            <DataTemplate DataType="{x:Type myns:Outer}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=Name}"/>
    
                    <TreeView ItemsSource="{Binding Path=Actions}" >
                        <DataTemplate DataType="{x:Type myns:Inner}">
                            <Button Command={Binding Path=OnClick}>
                                <TextBlock Text="{Binding Path=Description}"/>
                            </Button>
                        </DataTemplate>
                    </TreeView>
                </StackPanel>
            </DataTemplate>
        </TreeView.Resources>
    </TreeView>
    

    It seams like there's something wrong with this access since I get the following InvalidOperationException:

    Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.
    

    If I drop the inner TreeView there's no exception (but also no buttons of course).