CollectionView

Отображение списка с помощью CollectionView

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

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

Отличия от ListView:

  • CollectionView имеет гибкую модель компоновки, позволяя отображать данные вертикально или горизонтально, в виде списка или таблицы.

  • CollectionView поддерживает выбор как одного, так и нескольких элементов.

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

  • CollectionView автоматически использует виртуализацию, которая предоставляется нативными нижележащими элементами используемой операционной системы

  • CollectionView обладает меньшим API. Многие свойства и события из ListView отсутствуют в CollectionView.

  • CollectionView не поддерживает разделители элементов.

  • CollectionView сгенерирует исключение, если его свойство ItemsSource будет обновлено вне потока пользовательского интерфейса.

Определение источника данных

Для определения источника данных применяется свойство ItemsSource, которое в качестве значения принимает коллекцию IEnumerable. Например, определим следующую страницу в коде C#

class StartPage : ContentPage
{
    public StartPage()
    {
        CollectionView collectionView = new CollectionView { Margin=5 };
        collectionView.ItemsSource = new string[] { "Tom", "Sam", "Bob", "Alice", "Kate" }; 
        Content =  collectionView;
    }
}
CollectionView в .NET MAUI и C#

Установка шаблона данных

За установку шаблона отображения данных отвечает свойство ItemsTemplate, которое представляет объект DataTemplate и которое принимает в качестве значения одноименный объект DataTemplate. Простейший пример:

class StartPage : ContentPage
{
    public StartPage()
    {
        CollectionView collectionView = new CollectionView { Margin=5 };
        // определяем источник данных
        collectionView.ItemsSource = new string[] { "Tom", "Sam", "Bob", "Alice", "Kate" };
        // определяем шаблон данных
        collectionView.ItemTemplate = new DataTemplate(() => 
        {
            var personLbl = new Label { FontSize = 16, TextColor = Color.FromArgb("#1565C0") };
            personLbl.SetBinding(Label.TextProperty, new Binding("BindingContext", source: RelativeBindingSource.Self));
            return personLbl;
        });
         Content =  collectionView;
    }
}

Конструктор DataTemplate принимает делегат, который возвращает объект-шаблон элемента списка. В данном случае в качестве шаблона элемента выступает метка personLbl, для которой устанавливаются цвет текста и высота шрифта. Поскольку по умолчанию для объекта-шаблона в качестве контекста привязки (свойство BindingContext) используется отображаемый элемент списка, то для отображения текста в метке используется привязка к свойству BindingContext этой же метки (new Binding("BindingContext", source: RelativeBindingSource.Self)

Установка ItemsSource и ItemsTemplate для CollectionView в .NET MAUI и C#

Аналогичный пример в 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" >
    <CollectionView>
        <CollectionView.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>Tom</x:String>
                <x:String>Sam</x:String>
                <x:String>Bob</x:String>
                <x:String>Alice</x:String>
                <x:String>Kate</x:String>
            </x:Array>
        </CollectionView.ItemsSource>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Label Text="{Binding}" FontSize="16" TextColor="#1565C0" />
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

Определение шаблона для сложных данных

Как правило, объекты списока представляют более комплексные по структуре данные. Например, пусть у нас есть класс Person, который представляет пользователя:

public class Person
{
    public string Name { get; set; } = "";
    public int Age { get; set; }
    public string Company { get; set; } = "";
}

В коде C# определим страницу, которая выводит в CollectionView список пользователей:

namespace HelloApp;

class StartPage : ContentPage
{
    public StartPage()
    {
        CollectionView collectionView = new CollectionView();
        // определяем источник данных
        collectionView.ItemsSource = new List<Person>
        {
            new  Person { Name="Tom", Age=38, Company ="Microsoft" },
            new  Person { Name="Sam", Age=25,  Company ="Google" },
            new  Person { Name="Bob", Age=42,  Company ="JetBrains" },
            new  Person { Name="Alice", Age=33,  Company ="Microsoft" },
            new  Person { Name="Kate", Age=29,  Company ="Google" },
            new  Person { Name="Amelia", Age=35,  Company ="JetBrains" },
        };
        // определяем шаблон данных
        collectionView.ItemTemplate = new DataTemplate(() =>
        {
            var nameLabel = new Label { FontSize = 20, TextColor = Color.FromArgb("#006064"), Margin = 10 };
            nameLabel.SetBinding(Label.TextProperty, "Name");

            var ageLabel = new Label();
            ageLabel.SetBinding(Label.TextProperty, new Binding { Path = "Age", StringFormat = "Возраст: {0}" });

            var companyLabel = new Label();
            companyLabel.SetBinding(Label.TextProperty, "Company");

            return  new StackLayout
            {
                Children = { nameLabel, ageLabel, companyLabel },
                Margin = new Thickness(15, 10)
            };
        });
        Content =  collectionView ;
    }
}

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

Установка шаблона данных в CollectionView в .NET MAUI и C#

Аналогичный пример в 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"
             xmlns:local="clr-namespace:HelloApp">
    <CollectionView>
        <CollectionView.ItemsSource>
            <x:Array Type="{x:Type local:Person}">
                <local:Person Name="Tom" Age="38" Company="Microsoft"/>
                <local:Person Name="Sam" Age="25" Company="Google"/>
                <local:Person Name="Bob" Age="42" Company="JetBrains"/>
                <local:Person Name="Alice" Age="33" Company="Microsoft"/>
                <local:Person Name="Kate" Age="29" Company="Google"/>
                <local:Person Name="Amelia" Age="35" Company="JetBrains" />
            </x:Array>
        </CollectionView.ItemsSource>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout Margin="8">
                    <Label Text="{Binding Name}" FontSize = "20"  TextColor = "#006064" Margin="10" />
                    <Label Text="{Binding Age, StringFormat='Возраст: {0}'}" />
                    <Label Text="{Binding Company}" />
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

Заголовок и футер CollectionView

С помощью свойств Header и Footer у CollectionView можно задать соответственно заголовок и футер. В качестве значения мы можем задать обычные строки:

Например, в 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"
             xmlns:local="clr-namespace:HelloApp">
    <CollectionView Header="Список пользователей" Footer="Данные актуальны на январь 2023г.">
        <CollectionView.ItemsSource>
            <x:Array Type="{x:Type local:Person}">
                <local:Person Name="Tom" Company="Microsoft" />
                <local:Person Name="Bob" Company="Google" />
                <local:Person Name="Sam" Company="JetBrains" />
                <local:Person Name="Alice" Company="Microsoft" />
                <local:Person Name="Kate" Company="Google" />
            </x:Array>
        </CollectionView.ItemsSource>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout Padding="8">
                    <Label Text="{Binding Name}" FontSize="18" TextColor="#006064" />
                    <Label Text="{Binding Company}" />
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

Но в данном случае мы увидим небольшие надписи в начале и в конце списка:

Header и Footer в CollectionView в .NET MAUI и C#

Установка в коде C#:

CollectionView collectionView = new CollectionView();
collectionView.Header = "Список пользователей";
collectionView.Footer = "Январь 2023 г.";

Также CollectionView позволяет задать шаблон для их отображения:

<?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"
             xmlns:local="clr-namespace:HelloApp">
    <CollectionView>
        <CollectionView.ItemsSource>
            <x:Array Type="{x:Type local:Person}">
                <local:Person Name="Tom" Company="Microsoft" />
                <local:Person Name="Bob" Company="Google" />
                <local:Person Name="Sam" Company="JetBrains" />
                <local:Person Name="Alice" Company="Microsoft" />
                <local:Person Name="Kate" Company="Google" />
            </x:Array>
        </CollectionView.ItemsSource>
        <CollectionView.Header>
            <Label Text= "Список пользователей" FontSize="18" FontAttributes="Bold" />
        </CollectionView.Header>
        <CollectionView.Footer>
            <Label Text= "Январь 2023г." FontSize="14" FontAttributes="Italic" />
        </CollectionView.Footer>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout Padding="8">
                    <Label Text="{Binding Name}" FontSize="18" TextColor="#006064" />
                    <Label Text="{Binding Company}" />
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>
Настройка заголовка и футера в CollectionView в .NET MAUI и C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850