Tree View witch different data templates for master and child items

BitSmithy 2,206 Reputation points
2024-07-25T07:54:58.41+00:00

Hello,

I am trying to implement Tree View where I can show master and children data (two level data structure).

I have such data structure:

    public class Master
    {
        public string Name { get; set; }
        public string Desc { get; set; }
        public List<Child> Children { get; set; }
    }
    public class Child
    {
        public string s1 { get; set; }
        public string s2 { get; set; }
        public string s3 { get; set; }
    }

I have such data templates for master and child Items:

    <Page.Resources>        
         <DataTemplate x:Key="MasterTemplate" x:DataType="local:Master">
            <TreeViewItem ItemsSource="{x:Bind Children}" IsExpanded="True">
                <StackPanel Orientation="Horizontal">
                    <Button Content="AA"></Button>
                    <Button Content="BB"></Button>
                    <TextBlock Text="{x:Bind Name}" Margin="0,0,10,0"/>
                    <TextBlock Text="{x:Bind Desc}"/>
                </StackPanel>
            </TreeViewItem>
        </DataTemplate>

        <DataTemplate x:Key="ChildTemplate" x:DataType="local:Child">
            <StackPanel Orientation="Horizontal">
                <Button Content="CC"></Button>
                <Button Content="DD"></Button>
                <TreeViewItem Content="{x:Bind s1}"/>
                <TreeViewItem Content="{x:Bind s2}"/>
            </StackPanel>
         </DataTemplate>

        <local:TreeViewItemTemplateSelector x:Key="TreeViewItemTemplateSelector"
                                            MasterTemplate="{StaticResource MasterTemplate}"
                                            ChildTemplate="{StaticResource ChildTemplate}"/>
    </Page.Resources>

Such tree view:

        <TreeView x:Name="treeView" HorizontalAlignment="Center" VerticalAlignment="Center"
                       ItemTemplateSelector="{StaticResource TreeViewItemTemplateSelector}"/>

Such data template selector:

    public class TreeViewItemTemplateSelector : DataTemplateSelector
    {
        public DataTemplate MasterTemplate { get; set; }
        public DataTemplate ChildTemplate { get; set; }

        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            if (item is Master)
            {
                return MasterTemplate;
            }
            else if (item is Child)
            {
                return ChildTemplate;
            }

            return base.SelectTemplateCore(item, container);
        }
    }

But it doesnt work, first If I run this there is not visible a button which allows expand and hide children items

Developer technologies | Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Junjie Zhu - MSFT 21,646 Reputation points
    2024-07-29T10:16:29.8366667+00:00

    Hello @BitSmithy

    Welcome to Microsoft Q&A!

    Referring to the official example, you can see that class Item is reused in the sample. we need to design a class for treeview that calls itself repeatedly. Otherwise the code will not run.

        public class TreeViewInfo
        {
            public string Name { get; set; }
            public string Desc { get; set; }
            public bool isMaster { get; set; }
            public List<TreeViewInfo> Children { get; set; }
        }
    

    So we can't detect which class it is in SelectTemplateCore, even if I set a bool value, it can't be detected. This is by design, your requirement cannot be implemented in UWP Treeview.

    The following is my test code. This version is the closest to your needs, but the content of the button cannot be changed according to the role.

    <Grid>
        <TreeView x:Name="treeView" HorizontalAlignment="Center" VerticalAlignment="Center"  >
            <TreeView.ItemTemplate>
                <DataTemplate  x:DataType="local:TreeViewInfo">
                    <TreeViewItem ItemsSource="{x:Bind Children}" IsExpanded="True">
                        <StackPanel Orientation="Horizontal">
                            <Button Content="CC"></Button>
                            <Button Content="DD"></Button>
                            <TreeViewItem Content="{x:Bind Name}"/>
                            <TreeViewItem Content="{x:Bind Desc}"/>
                        </StackPanel>
                    </TreeViewItem>
                </DataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
    
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
                LoadData();
            }
            private void LoadData()
            {
                var infos = new List<TreeViewInfo>
                 {
                      new TreeViewInfo
                      {  
                          Name = "Parent 1", Desc = "AAAAAAAAA", isMaster=true,
                          Children = new List<TreeViewInfo>
                           {
                                new TreeViewInfo { Name = "Child 1", isMaster=false, },
                                new TreeViewInfo { Name = "Child 2", isMaster=false }
                            }
                       },
                    new TreeViewInfo
                    { 
                       Name = "Parent 2", Desc = "BBBBBBBBB", isMaster=true,
                       Children = new List<TreeViewInfo>
                       {
                            new TreeViewInfo { Name = "Child 3" , isMaster=false},
                            new TreeViewInfo { Name = "Child 4", isMaster=false }
                       }
                     }
                  };
                treeView.ItemsSource = infos;
            }
        }
        public class TreeViewInfo
        {
            public string Name { get; set; }
            public string Desc { get; set; }
            public bool isMaster { get; set; }
            public List<TreeViewInfo> Children { get; set; }
        }
    
    

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.