Grouped LongListSelector in Windows Phone 8 Silverlight

This article explains how to create a LongListSelector with grouping in a very simple and easy manner.

LongListSelector in Windows Phone 8 is a very flexible control.  You can use this control to implement Grouping of Items in the list.
 
Let us say we have some Categories and associated Sub-Categories as shown in the emulator snapshot below:
 
                      
 
XAML
 
Add a DataContext to phone:PhoneApplicationPage, I have used the MVVM Pattern. 
  1. DataContext="{Binding CatSubCat, Source={StaticResource Locator}}"  
LongListSelector: 
  1. <phone:LongListSelector ItemsSource="{Binding Categories}"  
  2. JumpListStyle="{StaticResource CategoryJumpListStyle}"  
  3. Background="Transparent"  
  4. GroupHeaderTemplate="{StaticResource CategoryHeaderTemplate}"  
  5. ItemTemplate="{StaticResource SubCategoryItemTemplate}"  
  6. LayoutMode="List"  
  7. IsGroupingEnabled="true"  
  8. HideEmptyGroups ="true"/>  
  9.    
So we need CategoryJumpListStyleCategoryHeaderTemplate, and SubCategoryItemTemplate.
 
Add them in PhoneApplicationPage.Resources as in the following:
  1. <phone:PhoneApplicationPage.Resources></phone:PhoneApplicationPage.Resources>  
CategoryJumpListStyle :
  1. <phone:JumpListItemBackgroundConverter x:Key="BackgroundConverter"/>    
  2.         <phone:JumpListItemForegroundConverter x:Key="ForegroundConverter"/>    
  3.         <Style x:Key="CategoryJumpListStyle" TargetType="phone:LongListSelector">    
  4.             <Setter Property="GridCellSize"  Value="220,150"/>    
  5.             <Setter Property="LayoutMode" Value="Grid" />    
  6.             <Setter Property="ItemTemplate">    
  7.                 <Setter.Value>    
  8.                     <DataTemplate>    
  9.                         <Border Background="{Binding Converter={StaticResource BackgroundConverter}}"  Height="150" Margin="10" >    
  10.                             <TextBlock TextWrapping="Wrap" Text="{Binding CategoryName}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="20" Padding="6"     
  11.                Foreground="{Binding Converter={StaticResource ForegroundConverter}}" TextAlignment="Center" VerticalAlignment="Center"/>    
  12.                         </Border>    
  13.                     </DataTemplate>    
  14.                 </Setter.Value>    
  15.             </Setter>    
  16.         </Style>    
CategoryHeaderTemplate :
  1. <DataTemplate x:Key="CategoryHeaderTemplate">  
  2.             <Border Background="Transparent" Padding="5">  
  3.                 <Border Background="{StaticResource PhoneAccentBrush}" BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="2" Width="400"   
  4.          Height="62" Margin="0,0,18,0" HorizontalAlignment="Left">  
  5.                     <TextBlock Text="{Binding CategoryName}" Foreground="{StaticResource PhoneForegroundBrush}" FontSize="24" Padding="6"   
  6.             FontFamily="{StaticResource PhoneFontFamilySemiLight}" HorizontalAlignment="Left" VerticalAlignment="Center"/>  
  7.                 </Border>  
  8.             </Border>  
  9.         </DataTemplate>  
SubCategoryItemTemplate: 
  1. <DataTemplate x:Key="SubCategoryItemTemplate">  
  2.            <StackPanel VerticalAlignment="Top">  
  3.                <TextBlock FontWeight="Bold"  Text="{Binding SubCategoryName}" />  
  4.   
  5.            </StackPanel>  
  6.        </DataTemplate>  
Code: 
LongListSelector for grouping needs an object of type: List<List<T>>. 

In our case we use List<T> as in the following:
  1. public class SubCategoryGroup : List<SubCategory>  
  2.    {  
  3.        public string CategoryName { getset; }  
  4.   
  5.        public SubCategoryGroup(IEnumerable<SubCategory> subCategoryList,string Name)  
  6.        {  
  7.            this.CategoryName = Name;  
  8.            this.AddRange(subCategoryList);  
  9.        }  
  10.    }  
And our View Model should return List<List<T>> (in our case List<SubCategoryGroup>) as in the following:
  1. public class CatSubCatViewModel : ViewModelBase  
  2.    {  
  3.        IRepository db;  
  4.        public List<SubCategoryGroup> Categories { getset; }  
  5.        public CatSubCatViewModel(IRepository _db)  
  6.        {  
  7.            db = _db;  
  8.            Categories = new List<SubCategoryGroup>();  
  9.   
  10.            var allCategories = db.GetAllCategories();  
  11.              
  12.            var allSubCategories = db.GetAllSubCategories();  
  13.   
  14.            foreach (var categoryItem in allCategories)  
  15.            {    
  16.               Categories.Add(new SubCategoryGroup(allSubCategories.Where(p => p.CategoryId == categoryItem.CategoryId),categoryItem.CategoryName));  
  17.            }  
  18.        }  
  19.   
  20.        
  21.    }  
So we have used the Categories Property to contain a List<SubCategoryGroup> that we directly bind to our LongListSelector.
 
That's all about the basics, you can customize it more depending on your requirements. I hope the article is helpful. Happy WP Coding!