Create Lists Inside Another List With Binding

Today, I'm going to show you how you can display a few lists either in an expandable ListView or ListBox.

Introduction

Once, when I was thinking about a problem in my developer project, I needed to initialize a list with some groups. GroupList would not work because there wouldn't be enough independence and I wanted separation of responsibility in the final result. Obviously, we need to do this with tough binding - x:Bind.

What is work environment?

  1. Project will start in VS 2015

  1. Type of app is UWP

What is the idea?

If we want to create one List inside another List, we need to use two types of models. Simple.

  1. Students will be inner List.

  1. GroupStudents outer List, which contains instances of inner List (Student).

Let's Go,

Step 1

Creating Student Model,
  1. public class Student  
  2. {  
  3.    public string Name { get; set; }  
  4. }  
Just a name. Nothing else.

Step 2

Creating GroupStudent Model,
  1. public class GroupStudent {  
  2.     public string HeaderListView {  
  3.         get;  
  4.         set;  
  5.     }  
  6.     public List < Student > StudentItems {  
  7.         get;  
  8.         set;  
  9.     }  
  10. }  
  • HeaderListView as you can see it will be a Header for each ListView.
  • StudentItems list with type of our first model. 
Step 3

Creating ViewModel
  1. public class ViewModel {  
  2.     private List < Student > _students {  
  3.         get;  
  4.         set;  
  5.     } = new List < Student > ();  
  6.     private ObservableCollection < GroupStudent > _groupstudents {  
  7.         get;  
  8.         set;  
  9.     } = new ObservableCollection < GroupStudent > ();  
  10.     public ObservableCollection < GroupStudent > GroupStudents {  
  11.         get {  
  12.             return _groupstudents;  
  13.         }  
  14.     }  
  15.     public void FillBothList() {  
  16.         _students.Add(new Student {  
  17.             Name = "Mike"  
  18.         });  
  19.         _students.Add(new Student {  
  20.             Name = "John"  
  21.         });  
  22.         _students.Add(new Student {  
  23.             Name = "Bob"  
  24.         });  
  25.         GroupStudents.Add(new GroupStudent {  
  26.             HeaderListView = "First ListView",  
  27.                 StudentItems = new List < Student > (_students)  
  28.         });  
  29.         GroupStudents.Add(new GroupStudent {  
  30.             HeaderListView = "Second ListView",  
  31.                 StudentItems = new List < Student > (_students)  
  32.         });  
  33.     }  
  34. }  
We have to make two Lists here.
  • _students Inner private list with type Student
  • GroupStudent ObservebleCollection with type GroupStudent, which will contain inside Header and instance of Inner List (_students). 
And one method FillBothList (I'm trying to do this simply). This method is adding three times instance to _students List. Then we are creating two instances of our outer GroupStudents list with two properties,
  1. HeaderListView.
  2. Instance of our inner list.
Step 4 

Organize MainPage 

In MainPage.xaml.cs we are creating viewmodel and calling method - FillBothList from eventhandler.
  1. public sealed partial class MainPage: Page {  
  2.     ViewModel viewmodel;  
  3.     public MainPage() {  
  4.         this.InitializeComponent();  
  5.         viewmodel = new ViewModel();  
  6.     }  
  7.     private void Button_Click(object sender, RoutedEventArgs e) {  
  8.         viewmodel.FillBothList();  
  9.     }  
  10. }   
Step 5 

Write a markup language

XAML code is an important part of all these steps. Understanding this is key to recognize binding.
  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">  
  2.     <Grid.RowDefinitions>  
  3.         <RowDefinition/>  
  4.         <RowDefinition Height="800" />  
  5.         <RowDefinition/> </Grid.RowDefinitions>  
  6.     <Grid.ColumnDefinitions>  
  7.         <ColumnDefinition Width="300" />  
  8.         <ColumnDefinition/> </Grid.ColumnDefinitions>  
  9.     <Button Grid.Row="1" Width="200" Height="50" HorizontalAlignment="Center" Content="Press" Click="Button_Click" />  
  10.     <ListView Grid.Column="1" // Outer ListView Grid.Row="1" SelectionMode="None" Width="800" ItemsSource="{x:Bind viewmodel.GroupStudents}">  
  11.         <ListView.ItemsPanel>  
  12.             <ItemsPanelTemplate>  
  13.                 <ItemsWrapGrid Orientation="Horizontal" /> </ItemsPanelTemplate>  
  14.         </ListView.ItemsPanel>  
  15.         <ListView.ItemTemplate>  
  16.             <DataTemplate x:DataType="local:GroupStudent">  
  17.                 <ListView Header="{x:Bind HeaderListView}" // Inner ListView ItemsSource="{x:Bind StudentItems}" Width="200">  
  18.                     <ListView.ItemTemplate>  
  19.                         <DataTemplate x:DataType="local:Student">  
  20.                             <TextBlock Text="{x:Bind Name}" Width="200" /> </DataTemplate>  
  21.                     </ListView.ItemTemplate>  
  22.                 </ListView>  
  23.             </DataTemplate>  
  24.         </ListView.ItemTemplate>  
  25.     </ListView>  
  26. </Grid>  
Step by step,
  1. Create the Button for starting process.
  2. Outer ListView with ItemSoucre of GroupStudents.
  3. ItemsWrapGrid - for horizontal initialize. Or you can use GridView.
  4. DataType of outer list.
  5. Inner ListView with Header property and ItemSource StudentItems, which was included like the property of GroupStudent list.
  6. DataType of inner list.
  7. TextBlock with one field Name which was included inside Student type.
ResultView
 

That's a scheme for a good understanding. I'll put it with high quality in the zip