locked
HierarchicalDataTemplate Second Level not showing. RRS feed

  • Question

  • I have been fighting this thing for too long now.  I am just not getting this apparently.  Can someone tell me what I am doing wrong with the xaml that is causing the second level to not show.

    Here is the code.

    XAML

    <TreeView Margin="0,0,0,0" ItemsSource="{Binding Path=Configuration.Servers}">
                    <TreeView.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Path=Reports}" DataType="{x:Type utils:CMSServer}">
                            <TextBlock Text="{Binding Path=Name}"/>
                            <HierarchicalDataTemplate.ItemTemplate>
                                <DataTemplate DataType="{x:Type utils:CMSReport}">
                                    <TextBlock Text="{Binding Path=Name}"/>
                                </DataTemplate>
                            </HierarchicalDataTemplate.ItemTemplate>
                        </HierarchicalDataTemplate>
                    </TreeView.ItemTemplate>
                </TreeView>

    Here is the underlying class

    C#:

    public class ConfigViewClass
        {
            private ObservableCollection<CMSServer> _servers;
            private string _key;
    
            public ConfigViewClass ()
            {
                _servers = new ObservableCollection<CMSServer>();
            }//constructor
    
            public ObservableCollection<CMSServer> Servers
            {
                get { return _servers; }
                set
                {
                    _servers = value;
                }
            }
    
            public string Key
            {
                get { return _key; }
                set
                {
                    _key = value;
                }
            }
    
            
        }//Configuration View
    
        public class CMSServer
        {
            public ObservableCollection<CMSReport> Reports { get; set; }
            public string Name { get; set; }
            
    
    
            public CMSServer ()
            {
                Reports = new ObservableCollection<CMSReport>();
            }//constructor
    
            
        }//CMS Server Class
    
        public class CMSReport
        {
            public string Name { get; set; }
            
            public CMSReport ()
            {
                
            }
            
        }//CMS Reports

    Greatly appreciate someone pointing out, what is sure to be a stupid mistake, for me.


    • Edited by Voast Dev Wednesday, October 3, 2018 1:54 PM
    Wednesday, October 3, 2018 1:53 PM

Answers

  • Hi Voast Dev,

    >>I have been fighting this thing for too long now.  I am just not getting this apparently.  Can someone tell me what I am doing wrong with the xaml that is causing the second level to not show

    I modify your code as the below. It can show the HierarchicalDataTemplate Second Level.

    XAML:

    <Window x:Class="Wpf_Example.HierarchicalDataTemplateSecond"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Wpf_Example"
            mc:Ignorable="d"
            Title="HierarchicalDataTemplateSecond" Height="450" Width="800" Loaded="Window_Loaded">
        <Grid>
            <TreeView x:Name="tettrii" Margin="0,0,0,0" ItemsSource="{Binding  Servers}">
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Path=Reports}" DataType="{x:Type local:CMSServer}">
                        <TextBlock Text="{Binding Path=Name}"/>
                        <HierarchicalDataTemplate.ItemTemplate>
                            <DataTemplate DataType="{x:Type local:CMSReport}">
                                <StackPanel>
                                    <TextBlock Text="{Binding Path=Name}"/>
                                    <TextBlock Text=" [ HierarchicalDataTemplate Second Level ] "/>
                                </StackPanel>
                            </DataTemplate>
                        </HierarchicalDataTemplate.ItemTemplate>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </Grid>
    </Window>
    XAML.CS:

     public partial class HierarchicalDataTemplateSecond : Window
        {
            public HierarchicalDataTemplateSecond()
            {
                InitializeComponent();
            }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                tettrii.DataContext = new ConfigViewClass();
            }
        }
    
        public class ConfigViewClass
        {
            private ObservableCollection<CMSServer> _servers;
            private string _key;
    
            public ConfigViewClass()
            {
                _servers = new ObservableCollection<CMSServer>();
                _servers.Add(new CMSServer() { Name = "CMSServer 001" });
                _servers.Add(new CMSServer() { Name = "CMSServer 002" });
                _servers.Add(new CMSServer() { Name = "CMSServer 003" });
                _servers.Add(new CMSServer() { Name = "CMSServer 004" });
            }//constructor
    
            public ObservableCollection<CMSServer> Servers
            {
                get { return _servers; }
                set
                {
                    _servers = value;
                }
            }
    
            public string Key
            {
                get { return _key; }
                set
                {
                    _key = value;
                }
            }
    
    
        }//Configuration View
    
        public class CMSServer
        {
            public ObservableCollection<CMSReport> Reports { get; set; }
            public string Name { get; set; }
    
    
    
            public CMSServer()
            {
                Reports = new ObservableCollection<CMSReport>();
                Reports.Add(new CMSReport() { Name = "test CMSReport 001" });
                Reports.Add(new CMSReport() { Name = "test CMSReport 002" });
                Reports.Add(new CMSReport() { Name = "test CMSReport 003" });
                Reports.Add(new CMSReport() { Name = "test CMSReport 004" });
            }//constructor
    
    
        }//CMS Server Class
    
        public class CMSReport
        {
            public string Name { get; set; }
    
            public CMSReport()
            {
    
            }
    
        }//CMS Reports

    Best Regards,

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Voast Dev Thursday, October 4, 2018 1:34 PM
    Thursday, October 4, 2018 2:37 AM

All replies

  • Hi Voast Dev,

    >>I have been fighting this thing for too long now.  I am just not getting this apparently.  Can someone tell me what I am doing wrong with the xaml that is causing the second level to not show

    I modify your code as the below. It can show the HierarchicalDataTemplate Second Level.

    XAML:

    <Window x:Class="Wpf_Example.HierarchicalDataTemplateSecond"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Wpf_Example"
            mc:Ignorable="d"
            Title="HierarchicalDataTemplateSecond" Height="450" Width="800" Loaded="Window_Loaded">
        <Grid>
            <TreeView x:Name="tettrii" Margin="0,0,0,0" ItemsSource="{Binding  Servers}">
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Path=Reports}" DataType="{x:Type local:CMSServer}">
                        <TextBlock Text="{Binding Path=Name}"/>
                        <HierarchicalDataTemplate.ItemTemplate>
                            <DataTemplate DataType="{x:Type local:CMSReport}">
                                <StackPanel>
                                    <TextBlock Text="{Binding Path=Name}"/>
                                    <TextBlock Text=" [ HierarchicalDataTemplate Second Level ] "/>
                                </StackPanel>
                            </DataTemplate>
                        </HierarchicalDataTemplate.ItemTemplate>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </Grid>
    </Window>
    XAML.CS:

     public partial class HierarchicalDataTemplateSecond : Window
        {
            public HierarchicalDataTemplateSecond()
            {
                InitializeComponent();
            }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                tettrii.DataContext = new ConfigViewClass();
            }
        }
    
        public class ConfigViewClass
        {
            private ObservableCollection<CMSServer> _servers;
            private string _key;
    
            public ConfigViewClass()
            {
                _servers = new ObservableCollection<CMSServer>();
                _servers.Add(new CMSServer() { Name = "CMSServer 001" });
                _servers.Add(new CMSServer() { Name = "CMSServer 002" });
                _servers.Add(new CMSServer() { Name = "CMSServer 003" });
                _servers.Add(new CMSServer() { Name = "CMSServer 004" });
            }//constructor
    
            public ObservableCollection<CMSServer> Servers
            {
                get { return _servers; }
                set
                {
                    _servers = value;
                }
            }
    
            public string Key
            {
                get { return _key; }
                set
                {
                    _key = value;
                }
            }
    
    
        }//Configuration View
    
        public class CMSServer
        {
            public ObservableCollection<CMSReport> Reports { get; set; }
            public string Name { get; set; }
    
    
    
            public CMSServer()
            {
                Reports = new ObservableCollection<CMSReport>();
                Reports.Add(new CMSReport() { Name = "test CMSReport 001" });
                Reports.Add(new CMSReport() { Name = "test CMSReport 002" });
                Reports.Add(new CMSReport() { Name = "test CMSReport 003" });
                Reports.Add(new CMSReport() { Name = "test CMSReport 004" });
            }//constructor
    
    
        }//CMS Server Class
    
        public class CMSReport
        {
            public string Name { get; set; }
    
            public CMSReport()
            {
    
            }
    
        }//CMS Reports

    Best Regards,

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Voast Dev Thursday, October 4, 2018 1:34 PM
    Thursday, October 4, 2018 2:37 AM
  • Appreciate the help greatly, you got me most of the way there.  I didn't set the DataContext on the treeview, that was a good idea. 

    Only problem left is when the ConfigViewClass changes it is not updating.  I bound the DataContext of the treeview to the property that calls the PropertyChangedEvent for that class and it fails to update.  It works great if I load the configuration ahead of time. The application though allows them to open and close different apps so I need it to reflect the current one.

    Here is what I bound it to.

    public ConfigViewClass Configuration
            {
                get { return _configuration; }
                set
                {
                    if( _configuration != value )
                    {
                        _configuration = value;
                        OnPropertyChanged("Configuration");
                    }
                }
            }

    I use this property to set the _configuration after I load a new config file.

    I will mark this as the answer anyways because you technically did answer the question.  Just hoping you can advise on the second part.

    Thanks

    Thursday, October 4, 2018 1:34 PM

  • Hi   Voast Dev,

    I am glad to know you solved your issue. Thank you for closed the thread by marking helpful solution as an answer. 

    Besides, You are supposed to post code snippets that anyone can use to reproduce your issue from scratch when you start a new thread or and upload your demo to OneDrive(Including your test material). We can download it and debugging. This will help us quickly analyze your problem.

    Thank you for your understanding.

    Best Regards,

    Yong Lu

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, October 5, 2018 9:05 AM