Расположение элементов в CollectionView

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

Элемент CollectionView по умолчанию располагает элементы вертикально. Однако вообще у нас есть 4 варианта расположения элементов:

  • Вертикальный список — список из одного столбца

  • Горизонтальный список — список из одной строки, который растет горизонтально по мере добавления новых элементов.

  • Вертикальный грид — грид из нескольких столбцов, который растет вертикально по мере добавления новых элементов.

  • Горизонтальный грид — грид из нескольких строкк, который увеличивается по горизонтали по мере добавления новых элементов.

С помощью свойства ItemsLayout можно настроить расположение. Это свойство представляет объект IItemsLayout. Обычно это объект класса, производного от ItemsLayout

Этот класс определяет свойство Orientation, которое представляет перечисление ItemsLayoutOrientation. В этом перечислении определены две константы:

  • Vertical: элементы располагаются вертикально

  • Horizontal: элементы располагаются горизонтально

По умолчанию .NET MAUI предоставляет две реализации класса ItemsLayout - LinearItemsLayout (для создания списка) и GridItemsLayout (для создания грида)

Списки

Для создания списков применяется класс LinearItemsLayout. Он определяет статические поля Vertical и Horizontal для создания вертикальных или горизонтальных списков соответственно. В качестве альтернативы можно создать объект LinearItemsLayout и передать в его конструктор одну из двух констант перечисления ItemsLayoutOrientation.

// вертикальный список
LinearItemsLayout layout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical);
// горизонтальный список
layout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal);

Кроме того, класс LinearItemsLayout определяет свойство ItemSpacing типа double, которое представояет пустое пространство вокруг каждого элемента. Значение этого свойства по умолчанию равно 0, и его значение всегда должно быть больше или равно 0.

Вертикальный список

По умолчанию для CollectionView определяется вертикальный список. И в принципе мы можем также явным образом задать вертикальное расположение. В коде C#:

collectionView.ItemsLayout = LinearItemsLayout.Vertical;
// или так
collectionView.ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical);

В коде xaml:

<CollectionView ItemsLayout="VerticalList">
    ...
</CollectionView>
<!-- или так -->
<CollectionView>
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Горизонтальный список

Горизонтальный список делается аналогично. В коде C#:

collectionView.ItemsLayout = LinearItemsLayout.Horizontal;
// или так
collectionView.ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal);

В коде xaml:

<CollectionView ItemsLayout="HorizontalList">
    ...
</CollectionView>
<!-- или так -->
<CollectionView>
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Horizontal" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Рассмотрим на примере. Допустим, данные представлены классом Person:

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

Класс Person определяет три свойства: Name, Age и Company для хранения имени, возраста и компании пользователя соответственно.

Определим в коде C# страницу, которая выводит список подобных объектов:

namespace HelloApp;
class StartPage : ContentPage
{
    public StartPage()
    {
        CollectionView collectionView = new CollectionView();
        collectionView.ItemsLayout = LinearItemsLayout.Horizontal;
        // определяем источник данных
        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 = 20
            };
        });
        Content =  collectionView ;
    }
}

Здесь шаблон элементов представлен объектом StackLayout, в котором в 3-х метках выводятся значения текущего объекта Person.

С помощью свойства ItemsLayout задаем горизонтальное направление элементов:

collectionView.ItemsLayout = LinearItemsLayout.Horizontal;

В итоге элементы будут располагаться в горизонтальный ряд:

Горизонтальный список в 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 ItemsLayout="HorizontalList">
        <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="10">
                    <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>

Отступы между элементами

С помощью свойства ItemSpacing можно задать отступы между элементами. Например, в xaml:

<CollectionView>
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Horizontal" ItemSpacing="20" />
    </CollectionView.ItemsLayout>
    .........
</CollectionView>

Или в коде C#

CollectionView collectionView = new CollectionView();
collectionView.ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal){ ItemSpacing = 10 };

Таблицы

Для создания гридов предназначен класс GridItemsLayout, который наследуется от класса ItemsLayout и определяет следующие свойства:

  • VerticalItemSpacing: значение типа double, которое представляет пустое пространство вокруг каждого элемента сверху и снизу. По умолчанию равно 0, и это значение всегда должно быть больше или равно 0.

  • HorizontalItemSpacing: значение типа double, которое представляет пустое пространство вокруг каждого элемента справа и слева. По умолчанию равно 0, и это значение всегда должно быть больше или равно 0.

  • Span: значение типа int, которое представляет количество столбцов или строк, отображаемых в гриде. По умолчанию равно 1 и всегда должно быть больше или равно 1.

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

Для создания грида необходимо присвоить свойству ItemsLayout объекта CollectionView объект GridItemsLayout c указанием ориентации и количеством строк/столбцов. Например, в коде C#:

CollectionView collectionView = new CollectionView();
// 2 столбца
collectionView.ItemsLayout = new GridItemsLayout(ItemsLayoutOrientation.Vertical) { Span = 2 };
// 2 строки
collectionView.ItemsLayout = new GridItemsLayout(ItemsLayoutOrientation.Horizontal) { Span = 2 };

В коде xaml можно использовать краткую форму

<CollectionView ItemsLayout="VerticalGrid, 2">

Сначала указывается ориентация - "VerticalGrid" или "HorizontalGrid", а затем количество строк/столбцов

Также можно использовать полную форму:

<CollectionView>
    <CollectionView.ItemsLayout>
        <GridItemsLayout Orientation="Vertical" Span="2" />
    </CollectionView.ItemsLayout>
    ...........
</CollectionView>

Вертикальный грид

Вертикальный грид представляет расположение элементов в несколько колонок/столбцов. Например, определим в C# вертикальный грид из двух колонок:

namespace HelloApp;
class StartPage : ContentPage
{
    public StartPage()
    {
        CollectionView collectionView = new CollectionView { VerticalOptions = LayoutOptions.Start};
        // 2 столбца
        collectionView.ItemsLayout = new GridItemsLayout(ItemsLayoutOrientation.Vertical) { Span = 2 };
        // определяем источник данных
        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 = 20
            };
        });
        Content =  collectionView ;
    }
}
Вертикальный грид в 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 ItemsLayout="VerticalGrid, 2">
        <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>

Горизонтальный грид

Определим горизонтальный грид из 3 строк в коде C#:

namespace HelloApp;
class StartPage : ContentPage
{
    public StartPage()
    {
        CollectionView collectionView = new CollectionView { VerticalOptions = LayoutOptions.Start};
        // три строки
        collectionView.ItemsLayout = new GridItemsLayout(ItemsLayoutOrientation.Horizontal) { Span = 3 };
        // определяем источник данных
        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" },
            new  Person { Name="Mike", Age=36,  Company ="Google" },
        };
        // определяем шаблон данных
        collectionView.ItemTemplate = new DataTemplate(() =>
        {
            var nameLabel = new Label { FontSize = 20, TextColor = Color.FromArgb("#006064")};
            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 = 8,
            };
        });
        Content =  collectionView ;
    }
}
Горизонтальный грид в 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 ItemsLayout="HorizontalGrid, 3" VerticalOptions="Start">
        <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" />
                <local:Person Name="Mike" Age="36" Company="Google"/>
            </x:Array>
        </CollectionView.ItemsSource>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout Margin="8">
                    <Label Text="{Binding Name}" FontSize = "20"  TextColor = "#006064"/>
                    <Label Text="{Binding Age, StringFormat='Возраст: {0}'}" />
                    <Label Text="{Binding Company}" />
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850