Xamarin.Forms Группирование CollectionView

Download Sample Скачайте пример

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

CollectionView поддерживает отображение сгруппированных данных и определяет следующие свойства, управляющие тем, как он будет представлен:

  • IsGroupedboolТип , указывает, должны ли базовые данные отображаться в группах. Значение по умолчанию этого свойства равно false.
  • GroupHeaderTemplate( тип DataTemplate— шаблон, используемый для заголовка каждой группы.
  • GroupFooterTemplateDataTemplateТип , шаблон, используемый для нижнего колонтитула каждой группы.

Эти свойства поддерживаются BindableProperty объектами, что означает, что свойства могут быть целевыми объектами привязки данных.

На следующих снимках экрана показаны CollectionView сгруппированные данные:

Screenshot of a grouped data in a CollectionView, on iOS and Android

Дополнительные сведения о шаблонах данных см. в разделе Общие сведения о шаблонах данныхXamarin.Forms.

Группирование данных

Перед отображением данных необходимо сгруппировать. Это можно сделать, создав список групп, где каждая группа является списком элементов. Список групп должен быть коллекцией IEnumerable<T> , где T определяется два фрагмента данных:

  • Имя группы.
  • Коллекция IEnumerable , определяющая элементы, принадлежащие группе.

Таким образом, процесс группировки данных заключается в том, чтобы:

  • Создайте тип, который моделирует один элемент.
  • Создайте тип, который моделирует одну группу элементов.
  • Создайте коллекцию IEnumerable<T> , где T используется тип, который моделирует одну группу элементов. Таким образом, эта коллекция представляет собой коллекцию групп, в которой хранятся сгруппированные данные.
  • Добавьте данные в коллекцию IEnumerable<T> .

Пример

При группировке данных первым шагом является создание типа, моделирующего один элемент. В следующем примере показан Animal класс из примера приложения:

public class Animal
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string ImageUrl { get; set; }
}

Класс Animal моделирует один элемент. Затем можно создать тип, который моделирует группу элементов. В следующем примере показан AnimalGroup класс из примера приложения:

public class AnimalGroup : List<Animal>
{
    public string Name { get; private set; }

    public AnimalGroup(string name, List<Animal> animals) : base(animals)
    {
        Name = name;
    }
}

Класс AnimalGroup наследует от List<T> класса и добавляет Name свойство, представляющее имя группы.

Затем можно создать коллекцию IEnumerable<T> групп:

public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();

Этот код определяет коллекцию с именем Animals, где каждый элемент в коллекции является AnimalGroup объектом. Каждый AnimalGroup объект состоит из имени и List<Animal> коллекции, которая определяет Animal объекты в группе.

Затем группированные данные можно добавить в коллекцию Animals :

Animals.Add(new AnimalGroup("Bears", new List<Animal>
{
    new Animal
    {
        Name = "American Black Bear",
        Location = "North America",
        Details = "Details about the bear go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbär.jpg"
    },
    new Animal
    {
        Name = "Asian Black Bear",
        Location = "Asia",
        Details = "Details about the bear go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
    },
    // ...
}));

Animals.Add(new AnimalGroup("Monkeys", new List<Animal>
{
    new Animal
    {
        Name = "Baboon",
        Location = "Africa & Asia",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
    },
    new Animal
    {
        Name = "Capuchin Monkey",
        Location = "Central & South America",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg"
    },
    new Animal
    {
        Name = "Blue Monkey",
        Location = "Central and East Africa",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg"
    },
    // ...
}));

Этот код создает две группы в Animals коллекции. Первый AnimalGroup называется Bearsи содержит коллекцию List<Animal> сведений о медведе. Второй AnimalGroup называется Monkeysи содержит коллекцию List<Animal> подробностей обезьяны.

Отображение сгруппированных данных

CollectionView отображает сгруппированные данные, если данные были правильно сгруппированы, задав IsGrouped для свойства trueзначение :

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                ...
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Эквивалентный код на C# выглядит так:

CollectionView collectionView = new CollectionView
{
    IsGrouped = true
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...

Внешний вид каждого элемента в объекте CollectionView определяется путем задания CollectionView.ItemTemplate свойства в значение DataTemplate. Дополнительные сведения см. в разделе "Определение внешнего вида элемента".

Примечание.

По умолчанию CollectionView будет отображаться имя группы в верхнем и нижнем колонтитуле группы. Это поведение можно изменить, настроив нижний колонтитул группы и нижний колонтитул группы.

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

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

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    ...
    <CollectionView.GroupHeaderTemplate>
        <DataTemplate>
            <Label Text="{Binding Name}"
                   BackgroundColor="LightGray"
                   FontSize="Large"
                   FontAttributes="Bold" />
        </DataTemplate>
    </CollectionView.GroupHeaderTemplate>
</CollectionView>

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

Screenshot of a customized group header in a CollectionView, on iOS and Android

Внешний вид каждого нижнего колонтитула группы можно настроить, задав CollectionView.GroupFooterTemplate для свойства DataTemplateзначение :

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    ...
    <CollectionView.GroupFooterTemplate>
        <DataTemplate>
            <Label Text="{Binding Count, StringFormat='Total animals: {0:D}'}"
                   Margin="0,0,0,10" />
        </DataTemplate>
    </CollectionView.GroupFooterTemplate>
</CollectionView>

В этом примере для каждого нижнего колонтитула группы задано Label значение, отображающее количество элементов в группе. На следующих снимках экрана показан настраиваемый нижний колонтитул группы:

Screenshot of a customized group footer in a CollectionView, on iOS and Android

Пустые группы

При отображении CollectionView сгруппированных данных будут отображаться все группы, которые пусты. Такие группы будут отображаться с верхним и нижним колонтитулом группы, указывая, что группа пуста. На следующих снимках экрана показана пустая группа:

Screenshot of an empty group in a CollectionView, on iOS and Android

Примечание.

В iOS 10 и нижнем колонтитуле групп для пустых групп могут отображаться в верхней части окна CollectionView.

Группа без шаблонов

CollectionViewможет отображать правильно сгруппированные данные, не устанавливая для DataTemplateсвойства значение CollectionView.ItemTemplate :

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true" />

В этом сценарии значимые данные можно отобразить, переопределив метод в типе, который моделирует ToString один элемент, и тип, который моделирует одну группу элементов.