Элемент 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 с помощью свойства 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, который привязан к названию группы: