Need help understanding HierarchicalDataTemplate

3 posts, 0 answers
  1. Todd Davis
    Todd Davis avatar
    36 posts
    Member since:
    Aug 2009

    Posted 20 Apr 2010 Link to this post

    (Sorry, I meant to put this in the Treeview Forum) :(

    I've spent several hours this morning trying to get this to work, but I'm at a loss. I'm sure I'm doing something stupid. Can someone please clue me in?

    I have an object called Procedures. (Not sure if I even need it, but...). Procedures has a list of Categories. Each Category has a Name and a list of Items (ProcedureData). Each ProcedureData has a Name and ID. This is probably simpler than it sounds.

        class ProcedureData 
        { 
            public string ProcedureName; 
            public int ProcedureID;     
        } 
     
        class Category 
        { 
            public string Name; 
            public List<ProcedureData> Items; 
             
            public Category(string name) 
            { 
                Items = new List<ProcedureData>(); 
                Name = name
            } 
        } 
     
        class Procedures 
        { 
            public List<Category> Categories; 
             
            public Procedures() 
            { 
                Categories = new List<Category>(); 
            } 
        } 

    All I want to do is Bind this to a TreeView control. I want to display the Categories as the root nodes, then the list of ProcedureNames as their child nodes. This is what I have so far.
            <telerik:HierarchicalDataTemplate x:Key="Cats" ItemsSource="{Binding Items}"
                <TextBlock Text="{Binding ProcedureName}" /> 
            </telerik:HierarchicalDataTemplate> 
            <telerik:HierarchicalDataTemplate x:Key="Procedures" ItemsSource="{Binding Categories}" ItemTemplate="{StaticResource Cats}"
                <TextBlock Text="{Binding Name}" /> 
            </telerik:HierarchicalDataTemplate> 
     
     
                <telerikNavigation:RadTreeView x:Name="ProcedureTree" IsRootLinesEnabled="True" IsLineEnabled="True" ItemTemplate="{StaticResource Procedures}" /> 
     

    I build the Procedures object in code-behind, populate it, and set it as the ProcedureTree.DataContext.

    The problem is, I get nothing. Nada. An empty tree. I did inspect the object(s) in the debugger, and I see all the items in the object that I expect to see.

    What am I doing wrong?



  2. Todd Davis
    Todd Davis avatar
    36 posts
    Member since:
    Aug 2009

    Posted 21 Apr 2010 Link to this post

    Never mind. I'm still not sure what exactly made the difference, but after messing with it for 24 hours, it finally works.
  3. DevCraft banner
  4. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 21 Apr 2010 Link to this post

    Hello Todd Davis,

    I am glad that you managed to get it working.

    Still, I examined the code snippet that you provided and I noticed a couple of things.

    Firstly, you said that you are setting the RadTreeView DataContext but I didn't see whether you also set the ItemsSource property. If your scenario requires you to set the DataContext property, like in your case, then you will also need to set the ItemsSource property of the TreeView to an IEnumerable collection. In this case you can use data binding, like so: ItemsSource = {Binding Categories}

    When you set the ItemsSource property, thus binding the RadTreeView to your Categories collection, you can change the  DataTemplates to match the changes, like so:
    <DataTemplate x:Key="Cats">
                <TextBlock Text="{Binding ProcedureName}" />
            </DataTemplate>
              
            <telerik:HierarchicalDataTemplate x:Key="Procedures"    
                              ItemsSource="{Binding Items}" 
                                         ItemTemplate="{StaticResource Cats}">
                <TextBlock Text="{Binding Name}" />
            </telerik:HierarchicalDataTemplate>

    The other thing that I noticed was that your classes have only fields and no properties. However you can only bind to public properties.

    I modified the code snippet accordingly to the suggestions:

    XAML:
        <UserControl.Resources>
      
            <DataTemplate x:Key="Cats">
                <TextBlock Text="{Binding ProcedureName}" />
            </DataTemplate>
              
            <telerik:HierarchicalDataTemplate x:Key="Procedures" 
                            ItemsSource="{Binding Items}" 
                            ItemTemplate="{StaticResource Cats}">
                <TextBlock Text="{Binding Name}" />
            </telerik:HierarchicalDataTemplate>
      
        </UserControl.Resources>
      
        <Grid x:Name="LayoutRoot">
              
            <telerikNavigation:RadTreeView x:Name="ProcedureTree" 
                          ItemsSource="{Binding Categories}"
                          IsRootLinesEnabled="True" 
                          IsLineEnabled="True" 
                          ItemTemplate="{StaticResource Procedures}" 
    />
              
        </Grid>
    </UserControl>


    C#
    public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
      
                Procedures proc = new Procedures();
      
                for (int j = 0; j < 5; j++)
                {
                    Category cat = new Category("Category" + j);
                    for (int i = 0; i < 5; i++)
                    {
                        ProcedureData procData = new ProcedureData();
                        procData.ProcedureID = i;
                        procData.ProcedureName = "Name" + i;
      
                        cat.Items.Add(procData);
                    }
      
                    proc.Categories.Add(cat);
                }
      
                this.ProcedureTree.DataContext = proc;
            }
      
            public class ProcedureData
            {
                public string ProcedureName { get; set; }
                public int ProcedureID { get; set; }
            }
      
            public class Category
            {
                public string Name { get; set; }
                public List<ProcedureData> Items { get; set; }
      
                public Category(string name)
                {
                    Items = new List<ProcedureData>();
                    Name = name;
                }
            }
      
            public class Procedures
            {
                public List<Category> Categories { get; set; }
      
                public Procedures()
                {
                    Categories = new List<Category>();
                }
            }
        }

    I hope this is helpfull. You can find more info about data binding here.

    Let us know if we can further assist you.

    Sincerely yours,
    Tina Stancheva
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Back to Top