Группировка в ListView

Последнее обновление: 23.01.2023

Элемент ListView в Xamarin поддерживает возможности группировки. Рассмотрим, как мы можем сгруппировать элементы в списке.

Допустим, наши данные представлены классом User:

public class User
{
    public string Name { get; set; } = "";
    public string Company { get; set; } = "";
}

Класс User определяет два свойства: для имени и для компании пользователя. Так как компания может совпадать у разных пользователей, то можно по этому признаку сгруппировать объекты User.

Для группировки в начале добавим в проект вспомогательный класс, который назовем Grouping:

using System.Collections.ObjectModel;

namespace HelloApp;

public class Grouping<K, T> : ObservableCollection<T>
{
    public K Name { get; private set; }
    public Grouping(K name, IEnumerable<T> items) : base(items)
    {
         Name = name;
    }
}

Класс Grouping типизирован двумя параметрами. Параметр K представляет тип ключа группы, который будет храниться в свойстве Name. А параметр T представляет тип объектов, которые будут храниться в коллекции Items. Это свойство-коллекция унаследовано от базового класса ObservableCollection. А в конструкторе мы получаем все необходимые данные.

В коде страницы MainPage.xaml.cs создадим список групп:

using System.Collections.ObjectModel;

namespace HelloApp;

public partial class MainPage : ContentPage
{
    // список групп, к которым идет привязка
    public ObservableCollection<Grouping<string, User>> UserGroups { get; set; }
    public MainPage()
	{
		InitializeComponent();

        // начальные данные
        var users = new List<User>
        {
                new User {Name="Tom", Company="Microsoft" },
                new User {Name="Sam", Company="Google" },
                new User {Name="Alice", Company="Microsoft" },
                new User {Name="Bob", Company="JetBrains" },
                new User {Name="Kate", Company="Google" },
        };
        // получаем группы
        var groups = users.GroupBy(p => p.Company).Select(g => new Grouping<string, User>(g.Key, g));
        // передаем группы в UserGroups
        UserGroups = new ObservableCollection<Grouping<string, User>>(groups);
        BindingContext = this;
    }
}

В конструкторе переменная users определяет общие данные, по которым создается коллекция групп в виде свойства UserGroups. Группировка в данном случае идет по свойству Company объекта User.

А в коде xaml у MainPage пропишем выражения привязки:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <StackLayout>
        <ListView  GroupDisplayBinding="{Binding Name}"
              ItemsSource="{Binding UserGroups}"
              IsGroupingEnabled="True">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding Name}" />
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

Привязка ListView здесь идет к свойству UserGroups, которое содержит группы. Установка свойства IsGroupingEnabled="True" добавляет в ListView поддержку групп.

С помошью свойства GroupDisplayBinding можно задать то значение, которое будет отображаться для каждой группы. В нашем случае идет привязка к имени группы, которое представляет критерий группировки.

И после запуска приложения все данные в списке будут сгруппированы по компаниям:

Группировка в ListView в .NET MAUI и C#

Настройка шаблона заголовков группы

ListView с помощью свойства GroupHeaderTemplate позволяет настроить шаблон отображения заголовков групп. Для этого изменим разметку xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <StackLayout Padding="5">
        <ListView ItemsSource="{Binding UserGroups}" IsGroupingEnabled="True">
            <ListView.GroupHeaderTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding Name}" 
                               BackgroundColor="LightGray"
                                FontSize="18"
                                FontAttributes="Bold" />
                    </ViewCell>
                </DataTemplate>
            </ListView.GroupHeaderTemplate>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding Name}" />
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

Свойство GroupHeaderTemplate получает шаблон DataTemplate, где мы можем настроить отображение. В данном случае заголовок будет представлять элемент Label, который привязан к названию группы:

Настройка заголовоков групп списков в ListView в .NET MAUI и C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850