A set of extension methods that can project Realm Xamarin collections to data bindable grouped collections that can be passed directly to a Xamarin.Forms ListView.
Just add the Realm.GroupedCollection package to your project.
// In your ViewModel
Students = realm.All<School>().ToGroupedCollection(school => school.Students);
This can then be passed to your ListView:
<ListView ItemsSource="{Binding Students}" IsGroupingEnabled="true" GroupDisplayBinding="{Binding Key.Name}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And your models would look something like:
class Student : RealmObject
{
public string Name { get; set; }
public School School { get; set; }
}
class School : RealmObject
{
public string Name { get; set; }
[Backlink(nameof(Student.School))]
public IQueryable<Student> Students { get; }
}
Both the returned collection and the inner collections are observable, so any changes will update the UI.
// Return schools ordered by Name, containing Students ordered by Age
var students = realm.All<School>().OrderBy(school => school.Name)
.ToGroupedCollection(school => school.Students.OrderBy(student => student.Age));
Supported query operations are limited by Realm's query support.
public class Dog : RealmObject
{
public string Name { get; set; }
}
public class Person : RealmObject
{
public IList<Dog> Dogs { get; }
}
var dogs = realm.All<Person>().ToGroupedCollection(person => person.Dogs);
Note that queries over IList
properties are not supported and will result in a runtime exception. This is the
case because those queries are executed by LINQ and not by Realm itself.
Usually, a .NET grouping would go from the specific to the general:
IEnumerable<Student> students = ...;
var groupedStudents = students.GroupBy(s => s.School);
Since Realm doesn't yet support grouping, we can achieve the same result by using backlinks (inverse relationships).
Then, the grouping goes from the general to the specific:
IQueryable<School> schools = realm.All<School>();
var groupedStudents = schools.ToGroupedCollection(s => s.Students);
This project is released under the MIT license.