Reputation: 1098
I have a ObservableRangeCollection Persons in my ViewModel which is bound in XAML to a CollectionView via ItemsSource. The DataTemplate is of Type Person, so they can be displayed.
Currently, I don’t know how I would do the grouping which is provided via IsGrouped-Option in the CollectionView.
How would I introduce the different Groups based on the first Letter of the Name of a Person, so that I have a Group „A“ with all Persons whose Name starts with letter „A“.
My ObservableRangeCollection is filled from values of a SQLite database which does not have groups, just the details for a Person.
Upvotes: 2
Views: 3498
Reputation: 10148
If you want to group the person based on first character
of the name of the Person, you can refer to the sample code below:
SAMPLE CODE:
XAML:
<CollectionView ItemsSource="{Binding Persons}" IsGrouped="True">
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<Label FontSize="18" FontAttributes="Bold" BackgroundColor="Gray" Text="{Binding Name}" />
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate>
<VerticalStackLayout>
<Label
Text="{Binding Name}"
FontAttributes="Bold" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
VIDEMODEL:
public class MainPageViewModel
{
public List<Person> origin_list { get; set; } = new List<Person>();
public List<Grouped_list> Persons { get; set; } = new List<Grouped_list>();
public MainPageViewModel()
{
//Pseudo data, you may retrieve the data from database and assign to it
origin_list.AddRange(new List<Person> {
new Person("Allan", "Male"),
new Person("Alex", "Male"),
new Person("Klay", "Male"),
new Person("Kate", "Female"),
new Person("Bob", "Male"),
new Person("Besley", "Male"),
new Person("John", "Male"),
new Person("Fiona", "Female")
});
//Group by the first letter
var dict = (origin_list.OrderBy(x=>x.Name)).GroupBy(o => o.Name.Substring(0,1)).ToDictionary(g => g.Key, g => g.ToList());
foreach(KeyValuePair<string, List<Person>> item in dict)
{
Persons.Add(new Grouped_list(item.Key, new List<Person>(item.Value)));
}
}
}
Grouped_list.cs
public class Grouped_list : List<Person>
{
public string Name { get; set; }
public Grouped_list(string name, List<Person> person):base(person)
{
Name = name;
}
}
MODEL:
public class Person
{
public string Name { get; set; }
public string Gender { get; set; }
public Person(string name, string gender)
{
Name = name;
Gender = gender;
}
}
OUTPUT:
Upvotes: 5
Reputation: 3907
My ObservableRangeCollection is filled from values of a SQLite database which does not have groups, just the details for a Person.
You speak as if this is something that has to remain like that. Obviously if you do not want to make groups, you wont be able to use grouping. So if you plan to keep it that way, I consider this question answered.
If you decide to create groups after all, the first thing you should do is bind to list of lists.
The outer list is simple. The inner list has property, that is used for grouping, and extends list.
To create those, you can modify the way you read them from the database, but if you do not want or know how to, and want to keep current reading, there is a way to use LINQ, in a way making another query for grouping, in similar way:
foreach( IGrouping<string, Model> group in NonGroupedList.GroupBy(s => s.Letter))
MyGroups.Add(new MyGroup(group.key, group.ToList()));
Upvotes: 0
Reputation: 69
I hope this helps you. Download ListView example => Grouping: Github
Upvotes: 0