How to implement checkbox in listview xamarin form - xamarin.forms

I am trying to implement checkbox in listview and retrieve the data from the selected rows. I tried searching online, but i am not finding any proper resource and some plugins are already not working anymore. Any reference and approach from anyone will be very kind.

You can use MVVM to achieve it. Here is running GIF.
First of all, you can create a Model. Add your need binding properties.
public class MyModel:BaseViewModel
{
public bool IsChecked { get; set; }
public string Title { get; set; }
}
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var changed = PropertyChanged;
if (changed != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Then create a Viewmodel to pop data.
public class MyViewModel
{
public ObservableCollection<MyModel> myModels { get; set; }
public MyViewModel()
{
myModels =new ObservableCollection<MyModel>();
myModels.Add(new MyModel() { IsChecked = false, Title = "test1" });
myModels.Add(new MyModel() { IsChecked = false, Title = "test2" });
myModels.Add(new MyModel() { IsChecked = false, Title = "test3" });
myModels.Add(new MyModel() { IsChecked = false, Title = "test4" });
myModels.Add(new MyModel() { IsChecked = false, Title = "test5" });
}
}
Then Create a layout to display the data.
<ListView x:Name="listView" ItemsSource="{Binding myModels}" ItemSelected="listView_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#eee"
Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked}"></CheckBox>
<Label Text="{Binding Title}" TextColor="#f35e20" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is background code for the layout, then retrieve the data from the selected rows and make a bindingContext.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new MyViewModel();
}
private void listView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var myModel=e.SelectedItem as MyModel;
DisplayAlert("title",myModel.Title+" "+myModel.IsChecked,"OK");
}
}

Related

Change Background Color of ListView Selected Item in Xamarin

I created a Master-Detail type project in Xamarin. When I selected an item from the Master page the background color is orange by default. How can I change this to a color of my choosing?
You can bind BackgroundColor for ContentView of ViewCell , then use ViewModel and ItemTapped method of ListView to modify the selected item background color .
For example , the xaml code as follow:
<ListView x:Name="ListViewMenu"
HasUnevenRows="True" ItemTapped="ListViewMenu_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<Grid Padding="10"
BackgroundColor="{Binding SelectedBackgroundColor}">
<Label Text="{Binding Title}" d:Text="{Binding .}" FontSize="20"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Then in HomeMenuItem model add SelectedBackgroundColor property :
public enum MenuItemType
{
Browse,
About
}
public class HomeMenuItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MenuItemType Id { get; set; }
public string Title { get; set; }
private Color selectedBackgroundColor;
public Color SelectedBackgroundColor
{
set
{
if (selectedBackgroundColor != value)
{
selectedBackgroundColor = value;
OnPropertyChanged("SelectedBackgroundColor");
}
}
get
{
return selectedBackgroundColor;
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then in MenuPage modify ItemSource as follow:
public partial class MenuPage : ContentPage
{
MainPage RootPage { get => Application.Current.MainPage as MainPage; }
List<HomeMenuItem> menuItems;
List<HomeMenuItem> tmpItems; // add a tmp list to remove setted backgroud color
public MenuPage()
{
InitializeComponent();
tmpItems = new List<HomeMenuItem>();
menuItems = new List<HomeMenuItem>
{
new HomeMenuItem {Id = MenuItemType.Browse, Title="Browse" },
new HomeMenuItem {Id = MenuItemType.About, Title="About" }
};
menuItems[0].SelectedBackgroundColor = Color.Red; // default set the first item be selected, you can modify as your wants
tmpItems.Add(menuItems[0]); // add the selected item (default is the first)
ListViewMenu.ItemsSource = menuItems;
ListViewMenu.SelectedItem = menuItems[0];
ListViewMenu.ItemSelected += async (sender, e) =>
{
if (e.SelectedItem == null)
return;
var id = (int)((HomeMenuItem)e.SelectedItem).Id;
await RootPage.NavigateFromMenu(id);
};
}
private void ListViewMenu_ItemTapped(object sender, ItemTappedEventArgs e)
{
menuItems[e.ItemIndex].SelectedBackgroundColor = Color.Red;
tmpItems[0].SelectedBackgroundColor = Color.Transparent;
tmpItems[0] = menuItems[e.ItemIndex];
}
}
The effect :
This problem is specific to Android. In the Android project add this line to Resources\values\styles.xml inside the <style> tag:
<item name="android:colorActivatedHighlight">#00FFFFFF</item>

Display Datagrid based on Binding item count in Xamarin Forms

I am currently using Syncfusion Sf Datagrid. I want to display the Datagrids based on count. For example I have button A and button B, if user click on A, it will display 1 datagrid. If user click on B, it will display 2 datagrid. FYI, the datagrid will display on the same page.
What my code does now is displaying all datagrid. I would like to display the datagrid only based on condition (in this case which is A or B). I am not sure how to achieve this because the datagrid is in xaml, how do I make sure the correct count of datagrid I want to appear? Let's say if I want to have more category that has different items, how do I display the correct number of datagrid according to the items inside a category?
MainPage.xaml
<ContentPage.Content>
<StackLayout>
<Button Text="A"/>
<Button Text="B"/>
<sfgrid:SfDataGrid ItemsSource="{Binding fruitA}"/>
<sfgrid:SfDataGrid ItemsSource="{Binding vegeB1}"/>
<sfgrid:SfDataGrid ItemsSource="{Binding vegeB2}"/>
</StackLayout>
</ContentPage.Content>
MainPage.cs
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new ViewModel();
}
}
ViewModel
public class ViewModel
{
public ObservableCollection<Test> fruitA { get; set; }
public ObservableCollection<Test> vegeB1 { get; set; }
public ObservableCollection<Test> vegeB2 { get; set; }
public ViewModel()
{
fruitA = new ObservableCollection<ChildPart>();
fruitA.Add(new Test() { Title = "Orange", Value = "1.20" });
fruitA.Add(new Test() { Title = "Banana", Value = "1.40" });
fruitA.Add(new Test() { Title = "Apple", Value = "1.30" });
vegeB1 = new ObservableCollection<ChildPart>();
vegeB1.Add(new Test() { Title = "Spinach", Value = "1.20" });
vegeB1.Add(new Test() { Title = "Cabbage", Value = "1.40" });
vegeB2 = new ObservableCollection<ChildPart>();
vegeB2.Add(new Test() { Title = "Lettuce", Value = "1.20" });
vegeB2.Add(new Test() { Title = "Broccoli", Value = "1.40" });
vegeB2.Add(new Test() { Title = "Celery", Value = "1.30" });
}
}
Test
public class Test
{
public string Title { get; set; }
public string Value { get; set; }
}
There is a way to use Bindable layouts to achieve that , you can check whether is your want .
Modify MainPage.xaml as follow (Add ScrollView if count of items is too much):
<StackLayout>
<Button Text="A" Clicked="Button_Clicked_A"/>
<Button Text="B" Clicked="Button_Clicked_B"/>
<Button Text="C" Clicked="Button_Clicked_C"/>
<ScrollView>
<StackLayout x:Name="MyStackLayout" Orientation="Vertical">
<BindableLayout.ItemTemplate>
<DataTemplate>
<sfgrid:SfDataGrid ItemsSource="{Binding }" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</StackLayout>
Modiy MainPage.cs asd follow :
public partial class MainPage : ContentPage
{
ViewModel viewModel;
public MainPage()
{
InitializeComponent();
viewModel = new ViewModel();
}
private void Button_Clicked_A(object sender, EventArgs e)
{
List<object> list = new List<object>();
list.Add(viewModel.fruitA);
BindableLayout.SetItemsSource(MyStackLayout, list);
}
private void Button_Clicked_B(object sender, EventArgs e)
{
List<object> list = new List<object>();
list.Add(viewModel.vegeB1);
list.Add(viewModel.vegeB2);
BindableLayout.SetItemsSource(MyStackLayout, list);
}
private void Button_Clicked_C(object sender, EventArgs e)
{
List<object> list = new List<object>();
list.Add(viewModel.fruitA);
list.Add(viewModel.vegeB1);
list.Add(viewModel.vegeB2);
BindableLayout.SetItemsSource(MyStackLayout, list);
}
}
After running , the effect as follow :
You can refer the following updated code snippet to achieve your requirement “Based on the button click I have to show respective datagrid”.
Code snippet:
<StackLayout>
<Button x:Name="A" Text="A" Clicked="A_Clicked" />
<Button x:Name="B1" Text="B1" Clicked="B1_Clicked" />
<Button x:Name="B2" Text="B2" Clicked="B2_Clicked" />
<sfgrid:SfDataGrid x:Name="fruitA" IsVisible="False" ItemsSource="{Binding fruitA}"/>
<sfgrid:SfDataGrid x:Name="vegeB1" IsVisible="False" ItemsSource="{Binding vegeB1}"/>
<sfgrid:SfDataGrid x:Name="vegeB2" IsVisible="False" ItemsSource="{Binding vegeB2}"/>
</StackLayout>
private void A_Clicked(object sender, EventArgs e)
{
//// Displays only fruit datagrid.
fruitA.IsVisible = true;
vegeB1.IsVisible = false;
vegeB2.IsVisible = false;
}
private void B1_Clicked(object sender, EventArgs e)
{
//// Displays only vegeB1 datagrid.
fruitA.IsVisible = false;
vegeB1.IsVisible = true;
vegeB2.IsVisible = false;
}
private void B2_Clicked(object sender, EventArgs e)
{
//// Displays only vegeB2 datagrid.
fruitA.IsVisible = false;
vegeB1.IsVisible = false;
vegeB2.IsVisible = true;
}
Sample link
Regards,
Pradeep Kumar

Xamarin forms tabbed page not retrieving data from in OnAppearing

I retrieve data from the Azure database to show one of the tabbed pages. when calling the method from ViewModel in OnAppearing not retrieve data, but when click the button it retrieves and shows on the page.
Please advice If I have constructed ViewModel and view correctly? if so why it doesn't work. ?
Connection manager:
public partial class DatabaseManager
{
static DatabaseManager defaultInstance = new DatabaseManager();
MobileServiceClient client;
IMobileServiceTable<Person> personTable;
private DatabaseManager()
{
this.client = new MobileServiceClient(Constants.AzureMobileAppURL);
this.personTable = client.GetTable<Person>();
}
public static DatabaseManager DefaultManager
{
get
{
return defaultInstance;
}
private set
{
defaultInstance = value;
}
}
public MobileServiceClient CurrentClient
{
get { return client; }
}
}
Model:
public class Person
{
[JsonProperty(PropertyName = "FirstName")]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
[JsonProperty(PropertyName = "DisplayName")]
public string DisplayName
{
get { return displayName; }
set { displayName = value; }
}
[JsonProperty(PropertyName = "LastName")]
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}
ViewModel:
public class ProfilePageViewModel : ViewModelBase
{
DatabaseManager manager;
string firstName = "";
string lastName = "";
string displayName = "";;
IMobileServiceTable<Person> personTable;
public ProfilePageViewModel()
{
manager = DatabaseManager.DefaultManager;
this.personTable = manager.CurrentClient.GetTable<Person>();
RefreshCommand = new Command(
execute: async () =>
{
try
{
await GetProfileAsync();
}
catch
{
}
});
}
public async Task GetProfileAsync()
{
try
{
IEnumerable<Person> items = await personTable
.Where(pserson => pserson.Active)
.ToEnumerableAsync();
foreach (var item in items)
{
FirstName = item.FirstName;
LastName = item.LastName;
DisplayName = item.DisplayName;
}
}
catch (Exception e)
{
}
}
public string FirstName
{
private set { SetProperty(ref firstName, value); }
get { return firstName; }
}
public string LastName
{
private set { SetProperty(ref lastName, value); }
get { return lastName; }
}
public string DisplayName
{
private set { SetProperty(ref displayName, value); }
get { return displayName; }
}
public ICommand RefreshCommand { private set; get; }
}
View:
ProfilePage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SLSNZ.Views.ProfilePage"
xmlns:controls="clr-
namespace:ImageCircle.Forms.Plugin.Abstractions;
assembly=ImageCircle.Forms.Plugin"
xmlns:local="clr-namespace:SLSNZ.ViewModels"
Title="Profile">
<ContentPage.Resources>
<ResourceDictionary>
<local:ProfilePageViewModel x:Key="viewModel">
</local:ProfilePageViewModel>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Icon>
<OnPlatform x:TypeArguments="FileImageSource">
<On Platform="iOS" Value="icon-profile.png" />
</OnPlatform>
</ContentPage.Icon>
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<StackLayout BindingContext="{StaticResource viewModel}">
<Label Text="Display Name"
TextColor="Gray"
FontSize="Small"
HorizontalOptions="Start" />
<Label Text="{Binding DisplayName}"
VerticalOptions="Center"
HorizontalOptions="Start"
VerticalOptions="Start/>
<Label Text="First Name"
TextColor="Gray"
FontSize="Small"
HorizontalOptions="Start" />
<Label Text="{Binding FirstName}"
FontSize="Large"
HorizontalOptions="Start"
VerticalOptions="Start" />
<Label Text="Last Name"
TextColor="Gray"
FontSize="Small"
HorizontalOptions="Start" />
<Label Text="{Binding LastName}"
FontSize="Large"
HorizontalOptions="Start"
VerticalOptions="Start" />
<Button Text="Refresh"
Command="{Binding RefreshCommand}"
Grid.Row="0" Grid.Column="1"/>
</StackLayout>
</ContentPage>
View:
ProfilePage.cs
public partial class ProfilePage : ContentPage
{
ProfilePageViewModel viewModel;
public ProfilePage()
{
InitializeComponent();
viewModel = new ProfilePageViewModel();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await viewModel.GetProfileAsync();
}
}
ViewModelBase:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value,
[CallerMemberName] string propertyName =
null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName
= null)
{
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(propertyName));
}
}
In your view by the time you await viewModel.GetProfileAsync(); The view will already render.
Your GetProfileAsync in the View Model does an await so will get the data then update it.
I suggest changing the IMobileServiceTable personTable to a property and implement a on Property change to notify the view that the data has changes.
So your viewmodel should implement INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
Then when the Data Changes you can notify it in the view model like:
OnPropertyChanged("personTable");
Also in your view change your code to:
pre-initialize the viewmodel:
public ProfilePage()
{
InitializeComponent();
SetViewModel();
}
protected async void SetViewModel()
{
viewmodel = await viewModel.GetProfileAsync();
}
This way you wont block the UI thread and when you call the OnPropertyChnage it will notify your view to update.
UPDATE:
I have created a small sample Xamarin project for you to demonstrate how you can bind and notify the view of changes.
You had a few issues in your view as well where your DisplayName label was not closed properly and you had duplicate properties for HorizontalOptions in some labels.
Download this Xamarin sample. It had hard coded data but will show you the flow of setting the data and the Binding Context of the View without locking the UI thread.
https://github.com/loanburger/54430503

Showing Empty Screen in FlowListView in Xaml Xamarin.Forms

How to do FlowListView in XAML Xamarin.Forms?
Here is my Code:
XAML:
<flv:FlowListView FlowColumnCount="3" SeparatorVisibility="None" HasUnevenRows="true" x:Name="grid_list" ItemsSource="{Binding list_grid}" HeightRequest="100" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Image Source="{Binding Image}" Margin="20" VerticalOptions="Fill" HorizontalOptions="Fill" XAlign="Center" YAlign="Center"/>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
CODE.cs
public partial class PlanCampaign_DetailPage : ContentPage
{
ObservableCollection<CarosualImages> list_grid { get; set; }
public PlanCampaign_DetailPage()
{
InitializeComponent();
this.BindingContext = this;
list_grid = new ObservableCollection<CarosualImages>()
{
new CarosualImages { Image="maharastra.jpg"},
new CarosualImages {Image="delhi.jpg"},
new CarosualImages {Image="delhi.jpg"},
new CarosualImages {Image="delhi.jpg"},
new CarosualImages {Image="delhi.jpg"},
};
grid_list.ItemsSource = list_grid;
}
ModelClass:
public class CarosualImages
{
public string Image { get; set; }
}
Could anyone tell that where i did mistake here, this is showing Empty Screen.
Here is the code for INotifyPropertyChanged
public class CarosualImages : INotifyPropertyChanged
{
private string _name = String.Empty;
public CarosualImages()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string ImageName
{
get { return _name; }
set
{
_name= value;
OnPropertyChanged();
}
}
}
Put Public before
ObservableCollection<CarosualImages> list_grid { get; set; }

Xamarin ListView Grouping results in blackscreen

I'm developing an app with Xamarin.Forms (xaml), but now i have a strange behavior with the grouping of the ListView
I have a ListView with a CustomCell if i display it without grouping everything works as expected, but if I set IsGroupingEnabled to true the screen is getting black.
Before Grouping:
With grouping
I have no idea what i'm missing or what i did wrong.
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:cell="clr-namespace:BrindaApp.Cells"
x:Class="BrindaApp.Tabs.MainTab" Title="Main">
<StackLayout>
<StackLayout Orientation="Horizontal">
<Entry Placeholder="Search" HorizontalOptions="StartAndExpand"></Entry>
<Image x:Name="image_Group" HorizontalOptions="End">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Group_Tapped" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout VerticalOptions="FillAndExpand">
<ListView ItemsSource="{Binding ProductSource}" HasUnevenRows="True" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" x:Name="mainListView"
RelativeLayout.HeightConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1,Constant=0}" IsPullToRefreshEnabled="True" BackgroundColor="Black"
GroupDisplayBinding="{Binding Category}" GroupShortNameBinding="{Binding Category}" IsGroupingEnabled="True">
<ListView.Resources>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<cell:ProductCell ImageUrl="{Binding ProductImageUrl}" Difficult="{Binding Difficult}" Titel="{Binding Titel}" IsFavorit="{Binding IsFavorit}" ProductId="{Binding ProductId}"
RelativeLayout.HeightConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.2,Constant=0}" Height="200" Tapped="ProductCell_Tapped"
></cell:ProductCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--</RelativeLayout>-->
</StackLayout>
</StackLayout>
<!--<Label Text="Some Text"/>-->
</ContentPage>
MainPage.xaml.cs
public partial class MainTab : ContentPage
{
ProductsViewModel viewModel;
public bool IsGrouped { get; set; }
public MainTab()
{
viewModel = new ProductsViewModel();
BindingContext = viewModel;
InitializeComponent();
viewModel.mainListView = mainListView;
image_Group.Source = ImageSource.FromResource("BrindaApp.Imgs.group.png");
}
private void ProductCell_Tapped(object sender, EventArgs e)
{
Navigation.PushAsync(new ProductDetails());
}
private void Group_Tapped(object sender, EventArgs e)
{
if(IsGrouped)
{
mainListView.IsGroupingEnabled = false;
}
else
{
mainListView.IsGroupingEnabled = true;
}
IsGrouped = !IsGrouped;
}
}
Model:
public class ProductModel
{
public string ProductImageUrl { get; set; }
public string Titel { get; set; }
public int Difficult { get; set; }
public bool IsFavorit { get; set; }
public string ProductId { get; set; }
public string Category { get; set; }
}
ViewModel
public class ProductsViewModel:BaseViewModel
{
public ListView mainListView;
ObservableCollection<ProductModel> productSource;
public ObservableCollection<ProductModel> ProductSource
{
get
{
return productSource;
}
set
{
productSource = value;
FirePropertyChanged("ProductSource");
}
}
public ICommand RefreshListView { get; set; }
public ProductsViewModel()
{
ProductSource = new ObservableCollection<ProductModel>();
ProductSource.Add(new ProductModel() { ProductImageUrl = "https://media-cdn.tripadvisor.com/media/photo-s/02/d7/5a/1c/essen-trinken.jpg", IsFavorit = true, Category = "Test" });
ProductSource.Add(new ProductModel() { ProductImageUrl = "https://www.burgerking.at/003_at/website/slider/17_028_pop_cheesemas16_at/17_028_pop_cheesemas16_at_startseitenslider_01_product_angusclaus.png", Category = "Test" });
ProductSource.Add(new ProductModel() { ProductImageUrl = "https://media-cdn.tripadvisor.com/media/photo-s/02/d7/5a/1c/essen-trinken.jpg", IsFavorit = true });
ProductSource.Add(new ProductModel() { ProductImageUrl = "https://www.burgerking.at/003_at/website/slider/17_028_pop_cheesemas16_at/17_028_pop_cheesemas16_at_startseitenslider_01_product_angusclaus.png", Category = "Test" });
FirePropertyChanged("ProductSource");
RefreshListView = new Command(() =>
{
//TODO refresh list
mainListView.IsRefreshing = false;
},
() =>
{
return true;
});
}
}
I'm struggeling here for days and cannot find an answer, hopefuly someone can help me.
As guid i used: https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/customizing-list-appearance/#Grouping
When reading the link you also referred to yourself, you are required to create a list of lists:
Create a list of lists (a list of groups, each group being a list of elements).
Right now, you just have a flat list which is most likely why you experience your issue.
An example, also taken from the same link, is as follows:
static PageTypeGroup()
{
List<PageTypeGroup> Groups = new List<PageTypeGroup> {
new PageTypeGroup ("Alfa", "A"){
new PageModel("Amelia", "Cedar", new switchCellPage(),""),
new PageModel("Alfie", "Spruce", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Ava", "Pine", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Archie", "Maple", new switchCellPage(), "grapefruit.jpg")
},
new PageTypeGroup ("Bravo", "B"){
new PageModel("Brooke", "Lumia", new switchCellPage(),""),
new PageModel("Bobby", "Xperia", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Bella", "Desire", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Ben", "Chocolate", new switchCellPage(), "grapefruit.jpg")
}
}
All = Groups; //set the publicly accessible list
}

Resources