title | description | type | page_title | slug | tags | res_type | ticketid |
---|---|---|---|---|---|---|---|
Binding SortDescriptors in CollectionView for .NET MAUI |
Learn how to use data binding with CollectionView SortDescriptors in .NET MAUI applications. |
how-to |
How to Bind SortDescriptors in .NET MAUI CollectionView |
bind-sortdescriptors-collectionview-net-maui |
collectionview, sortdescriptors, databinding, .net maui, observablecollection |
kb |
1677846 |
Version | Product | Author |
---|---|---|
9.0.0 | Telerik UI for .NET MAUI CollectionView | Dobrinka Yordanova |
In my application, I want to use data binding to bind to an ObservableCollection
of sort descriptors.
This knowledge base article also answers the following questions:
- How to dynamically sort items in a CollectionView using
SortDescriptors
in .NET MAUI? - How to bind
SortDescriptors
to a view model property in .NET MAUI? - How to update CollectionView sorting based on user input in .NET MAUI?
To bind the SortDescriptors
collection in a CollectionView to a property in the view model, follow these steps:
- Define the CollectionView in XAML and bind the
SortDescriptors
andItemsSource
to theViewModel
properties.
<Grid RowDefinitions="auto,*">
<VerticalStackLayout>
<Switch IsToggled="{Binding IsSortByName}" />
<Switch IsToggled="{Binding IsSortByAge}" />
</VerticalStackLayout>
<telerik:RadCollectionView x:Name="listView"
Grid.Row="1"
SortDescriptors="{Binding SortDescriptors, Mode=OneWayToSource}"
ItemsSource="{Binding Items}">
<telerik:RadCollectionView.ItemTemplate>
<DataTemplate>
<HorizontalStackLayout Spacing="10" >
<Label Text="{Binding Name}"/>
<Label Text="{Binding Age}"/>
</HorizontalStackLayout>
</DataTemplate>
</telerik:RadCollectionView.ItemTemplate>
</telerik:RadCollectionView>
</Grid>
- In the
ViewModel
, create properties for sorting and managing data. Implement logic to update the sort descriptors based on the user input.
public class ViewModel : NotifyPropertyChangedBase
{
private bool isSortByName;
private bool isSortByAge;
private ObservableCollection<SortDescriptorBase> sortDescriptors;
public ViewModel()
{
this.Items = GetData();
}
private static ObservableCollection<Person> GetData()
{
var items = new ObservableCollection<Person>();
items.Add(new Person { Name = "Tom", Age = 41 });
items.Add(new Person { Name = "Anna", Age = 32 });
items.Add(new Person { Name = "Peter", Age = 28 });
items.Add(new Person { Name = "Teodor", Age = 39 });
items.Add(new Person { Name = "Lorenzo", Age = 25 });
items.Add(new Person { Name = "Andrea", Age = 33 });
items.Add(new Person { Name = "Martin", Age = 36 });
items.Add(new Person { Name = "Alexander", Age = 29 });
items.Add(new Person { Name = "Maria", Age = 22 });
items.Add(new Person { Name = "Elena", Age = 27 });
items.Add(new Person { Name = "Stefano", Age = 44 });
items.Add(new Person { Name = "Jake", Age = 31 });
items.Add(new Person { Name = "Leon", Age = 28 });
return items;
}
public bool IsSortByName
{
get => this.isSortByName;
set => this.UpdateValue(ref this.isSortByName, value);
}
public bool IsSortByAge
{
get => this.isSortByAge;
set => this.UpdateValue(ref this.isSortByAge, value);
}
public ObservableCollection<Person> Items { get; set; }
public ObservableCollection<SortDescriptorBase> SortDescriptors
{
get
{
return this.sortDescriptors;
}
set
{
ObservableCollection<SortDescriptorBase> oldValue = this.sortDescriptors;
if (this.UpdateValue(ref this.sortDescriptors, value))
{
this.OnSortDescriptorsChanged(oldValue);
}
}
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
this.UpdateCorrespondingDescriptor(propertyName);
}
private void OnSortDescriptorsChanged(ObservableCollection<SortDescriptorBase> oldValue)
{
if (oldValue != null)
{
oldValue.CollectionChanged -= this.SortDescriptors_CollectionChanged;
}
if (this.sortDescriptors != null)
{
this.sortDescriptors.CollectionChanged += SortDescriptors_CollectionChanged;
}
this.UpdateFlags();
}
private void SortDescriptors_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
this.UpdateFlags();
}
private void UpdateCorrespondingDescriptor(string propertyName)
{
if (propertyName == nameof(this.IsSortByName))
{
this.EnsureDescriptor(nameof(Person.Name), this.IsSortByName);
}
else if (propertyName == nameof(this.IsSortByAge))
{
this.EnsureDescriptor(nameof(Person.Age), this.IsSortByAge);
}
}
private void EnsureDescriptor(string propertyName, bool include)
{
ObservableCollection<SortDescriptorBase> descriptors = this.SortDescriptors;
if (descriptors == null)
{
return;
}
SortDescriptorBase descriptor = this.TryGetDescriptor(propertyName);
if (include)
{
if (descriptor == null)
{
descriptors.Add(new PropertySortDescriptor { PropertyName = propertyName });
}
}
else
{
if (descriptor != null)
{
descriptors.Remove(descriptor);
}
}
}
private void UpdateFlags()
{
this.IsSortByName = this.TryGetDescriptor(nameof(Person.Name)) != null;
this.IsSortByAge = this.TryGetDescriptor(nameof(Person.Age)) != null;
}
private SortDescriptorBase TryGetDescriptor(string propertyName)
{
SortDescriptorBase descriptor = this.sortDescriptors?.FirstOrDefault(d => (d as PropertySortDescriptor)?.PropertyName == propertyName);
return descriptor;
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
- Ensure that property change notifications are properly propagated, and the
SortDescriptors
collection is updated accordingly when switches are toggled.
This approach allows for dynamic sorting of items in the CollectionView based on user input, by binding SortDescriptors
to a collection managed in the view model.
- [CollectionView Overview in .NET MAUI]({%slug collectionview-overview%})
- Data Binding in .NET MAUI
- Implementing Model-View-ViewModel (MVVM) in .NET MAUI