The
RadListViewcontrol is obsolete and will be removed in Q2 2026. Use the RadCollectionView control instead. TheRadCollectionViewis a complete, ground-up rewrite of the ListView. TheRadCollectionViewoffers improved performance, enhanced features, and a modernized approach to managing lists of data. TheRadCollectionViewincorporates all of the ListView's key features. More about the differences between both components and how to migrate to the newRadCollectionViewis available in the Migrating the Telerik .NET MAUI RadListView to RadCollectionView article.
.NET MAUI ListView Bindable GroupDescriptor
The GroupDescriptor collection now can be controlled by users using MVVM.
To control the GroupDescriptor collection through MVVM:
Create a property of type ObservableCollection<GroupDescriptorBase> in your ViewModel which will contain the needed group descriptors:
public class ViewModel : NotifyPropertyChangedBase
{
private ObservableCollection<GroupDescriptorBase> groupDescriptors;
private bool isPropertyNameGroupSwitchToggled;
private bool isSortOrderGroupSwitchToggled;
private List<Event> items;
public ViewModel()
{
this.Items = this.GetItems();
this.groupDescriptors = new ObservableCollection<GroupDescriptorBase>();
}
public ObservableCollection<GroupDescriptorBase> GroupDescriptors
{
get { return this.groupDescriptors; }
set { this.UpdateValue(ref this.groupDescriptors, value); }
}
public bool IsPropertyNameGroupSwitchToggled
{
get { return this.isPropertyNameGroupSwitchToggled; }
set
{
if (this.UpdateValue(ref this.isPropertyNameGroupSwitchToggled, value))
{
this.UpdateExistingGroupDescriptor(nameof(IsPropertyNameGroupSwitchToggled));
}
}
}
public bool IsSortOrderGroupSwitchToggled
{
get { return this.isSortOrderGroupSwitchToggled; }
set
{
if (this.UpdateValue(ref this.isSortOrderGroupSwitchToggled, value))
{
this.UpdateExistingGroupDescriptor(nameof(IsSortOrderGroupSwitchToggled));
}
}
}
public List<Event> Items
{
get { return this.items; }
set { this.UpdateValue(ref this.items, value); }
}
private List<Event> GetItems()
{
var results = new List<Event>();
results.Add(new Event() { Content = "Content of the item", Day = "Tommorow", Category = "A" });
results.Add(new Event() { Content = "This also happens today", Day = "Yesterday", Category = "A" });
results.Add(new Event() { Content = "More events today", Day = "Today", Category = "A" });
results.Add(new Event() { Content = "Go shopping after 19:00", Day = "Yesterday", Category = "B" });
results.Add(new Event() { Content = "You are now free to do whathever", Day = "Today", Category = "B" });
results.Add(new Event() { Content = "For tommorow", Day = "Today", Category = "B" });
results.Add(new Event() { Content = "It is a free day", Day = "Yesterday", Category = "C" });
results.Add(new Event() { Content = "Go have some fun", Day = "Tommorow", Category = "C" });
results.Add(new Event() { Content = "Party", Day = "Tommorow", Category = "C" });
return results;
}
private void UpdateExistingGroupDescriptor(string propertyToUpdate)
{
if (this.GroupDescriptors == null)
return;
if (this.GroupDescriptors.Count == 0)
{
this.GroupDescriptors.Add(new ListViewPropertyGroupDescriptor()
{
PropertyName = "Day",
SortOrder = Telerik.Maui.Controls.Data.SortOrder.Ascending
});
}
if (propertyToUpdate.Equals(nameof(IsSortOrderGroupSwitchToggled)))
{
var descriptor = (ListViewPropertyGroupDescriptor)this.GroupDescriptors.FirstOrDefault();
descriptor.SortOrder = isSortOrderGroupSwitchToggled ? Telerik.Maui.Controls.Data.SortOrder.Descending : Telerik.Maui.Controls.Data.SortOrder.Ascending;
}
else if (propertyToUpdate.Equals(nameof(IsPropertyNameGroupSwitchToggled)))
{
var descriptor = (ListViewPropertyGroupDescriptor)this.GroupDescriptors.FirstOrDefault();
descriptor.PropertyName = isPropertyNameGroupSwitchToggled ? "Category" : "Day";
}
}
}
Use the OneWayToSource binding mode to bind that property to the GroupDescriptors property of RadListView:
<Grid Margin="16,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition />
</Grid.RowDefinitions>
<HorizontalStackLayout>
<VerticalStackLayout>
<Label Text="Group Descending" />
<Label Text="Updates group descriptor" FontSize="Micro" TextColor="LimeGreen" />
</VerticalStackLayout>
<Switch IsToggled="{Binding IsSortOrderGroupSwitchToggled, Mode=TwoWay}" AutomationId="GroupSortingSwitch"/>
</HorizontalStackLayout>
<HorizontalStackLayout Grid.Row="1">
<VerticalStackLayout>
<Label Text="Group Day/Category" />
<Label Text="Updates existing group descriptor" FontSize="Micro" TextColor="LimeGreen" />
</VerticalStackLayout>
<Switch IsToggled="{Binding IsPropertyNameGroupSwitchToggled, Mode=OneWayToSource}" AutomationId="GroupOrderSwitch"/>
</HorizontalStackLayout>
<telerik:RadListView x:Name="listView"
Grid.Row="2"
GroupDescriptors="{Binding GroupDescriptors, Mode=OneWayToSource}"
ItemsSource="{Binding Items}">
<telerik:RadListView.GroupHeaderTemplate>
<DataTemplate>
<Label Text="{Binding }" TextColor="Violet" FontSize="Large" HorizontalOptions="CenterAndExpand" />
</DataTemplate>
</telerik:RadListView.GroupHeaderTemplate>
<telerik:RadListView.ItemTemplate>
<DataTemplate>
<telerik:ListViewTemplateCell>
<telerik:ListViewTemplateCell.View>
<Grid RowDefinitions="Auto,Auto,Auto">
<Label Text="{Binding Content}" FontSize="Medium" />
<Label Text="{Binding Day}" FontSize="Small" TextColor="LimeGreen" Grid.Row="1"/>
<Label Text="{Binding Category}" FontSize="Micro" TextColor="Red" Grid.Row="2"/>
</Grid>
</telerik:ListViewTemplateCell.View>
</telerik:ListViewTemplateCell>
</DataTemplate>
</telerik:RadListView.ItemTemplate>
</telerik:RadListView>
Here is how the GroupDescriptor collection looks like through MVVM:

For the ListView Bindable GroupDescriptor example, go to the SDKBrowser Demo Application and navigate to ListView -> Grouping category.