Just started to master data binding in wpf, I can not figure out how to make a nested grouping of data in treeview.

There is a class

public class Track { public int year {get;set;} public string Name {get;set;} public string Category {get;set} } 

I want to display in treeview with grouping:

 +---2010 | +---Rap | | Track 1 | | Track 2 | | | \---Rock | Track 5 | Track 6 | +---2011 +---Rap | Track 7 | Track 10 | \---Rock Track 11 

In the code, I create the observable ObservableCollection<Track> items = new ObservableCollection<Track>() and fill it. Then I specify the data source for treeview: treeview.ItemsSource = items;

Further, as far as I understand, I need a HierarchicalDataTemplate. But I can not make them nested.

Now I manually create a TreeViewItem with the year, I add a child to it with a category, and to it the name of the track. I understand that this is not correct, so I want to understand how to group with the help of xaml.

  • It seems you are doing everything right. And show your HierarchicalDataTemplate . - VladD
  • @VladD Now my code is not working. I'm trying to first learn to somehow group the data pastebin.com/H5mAwnNR . I think if I understand, the meaning will be something like this: there are 2 collectionviewsource, to one we bind a collection of items and it will group by years; in the second, we tie the result of the first one and group it into categories. - CrazyAlex25

2 answers 2

If you have a hierarchical data structure or to which you will lead in the future, for example to this:

 public class Track { public string Name { get; set; } //--- } public class Category { public string CategoryName { get; set; } public ObservableCollection<Track> Tracks { get; set; } //---- } public class Album { public int Year { get; set; } public ObservableCollection<Category> Categories { get; set; } //---- } public ObservableCollection<Album> Albums {get; set;} 

This is done as follows:

Let's start making the tree template from the bottom level. So, at the lower level is the name of the track, because by the condition it does not have children, then we define a simple DataTemplate template:

 <DataTemplate x:Key="trackTemplate"> <TextBlock Text="{Binding Name}" /> </DataTemplate> 

Next we go up one level and define a template for the category. There are already child elements here, so we define a HierarchicalDataTemplate , and in the ItemTemplate specify a previously defined template:

 <HierarchicalDataTemplate x:Key="categoryTemplate" ItemTemplate="{StaticResource trackTemplate}" <!--здесь указывается шаблон для дочерних элементов --> ItemsSource="{Binding Tracks}"> <TextBlock Text="{Binding CategoryName}"/> </HierarchicalDataTemplate> 

Another level up, the highest level with the year. In the ItemTemplate specify the categoryTemplate template

 <HierarchicalDataTemplate x:Key="yearsTemplate" ItemTemplate="{StaticResource categoryTemplate}" ItemsSource="{Binding Сategories}"> <TextBlock Text="{Binding Year}" /> </HierarchicalDataTemplate> 

When declaring a tree, you need to specify a template for only one level, for the highest one.

 <TreeView ItemTemplate="{StaticResource yearsTemplate}" ItemsSource="{Binding Albums}"/> 
  • thank you very much! Do I understand correctly that the templates are only pulling related data? Do they determine how collections will be displayed inside other classes? And another question: is it possible to also group a flat list as I originally did? - CrazyAlex25
  • @ CrazyAlex25, templates describe how objects in a view will look. I do not understand what it means to "pull out." The tree grows due to the fact that we specify the ItemTemplate, which in turn is also a tree. Regarding the second question, I can’t say, I think it's better to initially design the architecture correctly. - Gardes

An example of a "final" hierarchy is given. When it is known how many levels of nesting a tree has. What to do n level of nesting?

 class A { UInt64 ID {get;set;} UInt64 ParentID {get;set} string Description {get;set} } ObservableCollection<A> 

ID - record ID, ParentID - link to parent ID . At the top level branches, respectively, ParentID = 0 . Nesting levels can be any number. For example, any arbitrary classifier of something .....