New to Telerik UI for .NET MAUI? Start a free 30-day trial

.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:

.NET MAUI ListView Group Descriptors MVVM

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

See Also

In this article