And so, for the implementation of this task, we should first acquire a certain class, which we indicate to our application as a certain data source for binding ( DataContext ), let it be an empty class with the name MyDataClass at the moment:
public class MyDataClass { }
Good. Next, we need to create the simplest class for one item in our list. Let it contain some string variable named Name and a certain List<string> collection named Films . The class itself is called Category :
public class Category { public string Name { get; set; } public List<string> Films { get; set; } }
Good! Now you can create an empty (currently) ObservableCollection<> in the previously created MyDataClass class. Let's call it MyCategory and let it be initially initialized. Our class will be like this:
public class MyDataClass { public ObservableCollection<Category> MyCategory { get; set; } = new ObservableCollection<Category>(); }
Ok, half of the way is covered, the design of the elements is left and everything is connected. Let's get in touch first! In the MainWindow at the very beginning, create our MyDataClass :
public partial class MainWindow : Window { private MyDataClass MyData; }
Then after InitializeComponent(); we need to initialize this class and set it as a DataContext . Also, let's immediately and fill all this with some data for the test:
public MainWindow() { InitializeComponent(); MyData = new MyDataClass(); DataContext = MyData; MyData.MyCategory.Add(new Category { Name = "Боевики", Films = new List<string> { "Фильм 1", "Фильм 2", "Фильм 3" } }); MyData.MyCategory.Add(new Category { Name = "Комедии", Films = new List<string> { "Фильм 1", "Фильм 2", "Фильм 3" } }); }
Well, almost finish. It remains to create a display element. In WPF counting each element can contain a bunch of others (for example, we can shove a picture, text, or something else into the button). In our case, we can override the element template at the ListBox to the one that would contain a text field and another ListBox :
<ListBox ItemsSource="{Binding MyCategory}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Name}"/> <ListBox ItemsSource="{Binding Films}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Notice, I have already specified the data for binding above, namely:
- The main
ListBox has ItemsSource="{Binding MyCategory}" , which links it to the data in our MyCategory collection TextBlock - he indicated the place from where he should take the text Text="{Binding Name}" . That is, the bound collection MyCategory contains elements of type Category (our created collection for one element), that’s where we specified Name and we finally attached to it.- Internal
ListBox - well, here it is already clear, we gave him the data to our Films list.
Well, let's run. The result should be as follows:

If you switch to Binding , then in this case, if you change a collection of any elements, you most likely will not update the data visually. This frightens many (personally, I have many friends who are repelled by this fact from Binding 'a.) By this I’ll write how to fight! Everything is simple, you need to implement INotifyPropertyChanged where something may change. In our case, this is the Category class. Let's add a couple of lines to it:
public class Category: INotifyPropertyChanged { public string Name { get; set; } public List<string> Films { get; set; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
Now we have to rewrite what can be updated, for example, the name:
private string name; public string Name { get => name; set { name = value; OnPropertyChanged("Name"); } }
That's all, now our interface will update the "Name" field (Name) in accordance with the changes in the MyCategory collection. For lists, it is better to use ObservableCollection as it can notify about data changes.
What you need is just an example of how to place a ListBox inside another ListBox , but I thought it would be useful for you to learn how to tie up all the data and how to use it, because these are the basics and the most juice of WPF . I tried to paint everything as detailed as possible for clarity. I hope helped. Good luck!