Указание макета CollectionView
Пользовательский интерфейс многоплатформенного приложения .NET (.NET MAUI) CollectionView определяет следующие свойства, которые управляют макетом:
ItemsLayout
IItemsLayout
Тип , указывает используемый макет.ItemSizingStrategy
ItemSizingStrategy
Тип , указывает стратегию измерения элемента, которую следует использовать.
Эти свойства поддерживаются BindableProperty объектами, что означает, что свойства могут быть целевыми объектами привязки данных.
По умолчанию CollectionView элемент будет отображаться в вертикальном списке. Однако можно использовать любой из следующих макетов:
- Вертикальный список — один список столбцов, который увеличивается по вертикали по мере добавления новых элементов.
- Горизонтальный список — один список строк, который увеличивается горизонтально по мере добавления новых элементов.
- Вертикальная сетка — сетка с несколькими столбцами, которая растет вертикально по мере добавления новых элементов.
- Горизонтальная сетка — сетка с несколькими строками, которая растет горизонтально по мере добавления новых элементов.
Эти макеты можно указать, задав свойству ItemsLayout
класс, производный ItemsLayout
от класса. Этот класс определяет приведенные ниже свойства.
Orientation
ItemsLayoutOrientation
Тип , указывает направление, в котором CollectionView добавляются элементы.SnapPointsAlignment
Тип , указывает, как точки привязкиSnapPointsAlignment
выравниваются с элементами.SnapPointsType
SnapPointsType
Тип , указывает поведение точек оснастки при прокрутке.
Эти свойства поддерживаются BindableProperty объектами, что означает, что свойства могут быть целевыми объектами привязки данных. Дополнительные сведения о точках оснастки см. в разделе "Точки оснастки" в элементе управления прокруткой в CollectionView.
Перечисление ItemsLayoutOrientation
определяет следующие члены:
Vertical
указывает, что CollectionView будет развернуто по вертикали по мере добавления элементов.Horizontal
указывает, что CollectionView будет развернуто горизонтально по мере добавления элементов.
Класс LinearItemsLayout
наследует ItemSpacing
от ItemsLayout
класса и определяет свойство типаdouble
, представляющее пустое пространство вокруг каждого элемента. Значение по умолчанию этого свойства равно 0, а его значение всегда должно быть больше или равно 0. Класс LinearItemsLayout
также определяет статические Vertical
и Horizontal
члены. Эти элементы можно использовать для создания вертикальных или горизонтальных списков соответственно. Кроме того, LinearItemsLayout
можно создать объект, указав ItemsLayoutOrientation
элемент перечисления в качестве аргумента.
Класс GridItemsLayout
наследует от ItemsLayout
класса и определяет следующие свойства:
VerticalItemSpacing
double
Тип , представляющий вертикальное пустое пространство вокруг каждого элемента. Значение по умолчанию этого свойства равно 0, а его значение всегда должно быть больше или равно 0.HorizontalItemSpacing
double
Тип , представляющий горизонтальное пустое пространство вокруг каждого элемента. Значение по умолчанию этого свойства равно 0, а его значение всегда должно быть больше или равно 0.Span
int
Тип , представляющий количество столбцов или строк, отображаемых в сетке. Значение по умолчанию этого свойства равно 1, а его значение всегда должно быть больше или равно 1.
Эти свойства поддерживаются BindableProperty объектами, что означает, что свойства могут быть целевыми объектами привязки данных.
Примечание.
CollectionView использует собственные подсистемы макета для выполнения макета.
Вертикальный список
По умолчанию CollectionView будут отображаться его элементы в вертикальном макете списка. Поэтому не обязательно задать ItemsLayout
свойство для использования этого макета:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<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>
Однако для полноты в XAML CollectionView можно задать для отображения его элементов в вертикальном списке, задав для свойства значение ItemsLayout
VerticalList
:
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="VerticalList">
...
</CollectionView>
Кроме того, это можно сделать, задав ItemsLayout
ItemsLayoutOrientation
Vertical
свойство LinearItemsLayout
объекту, указав элемент перечисления в качестве Orientation
значения свойства:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Vertical
};
Это приводит к созданию одного списка столбцов, который увеличивается по вертикали по мере добавления новых элементов:
Совет
CollectionView Размещение внутри VerticalStackLayout может остановить прокрутку CollectionView и может ограничить количество отображаемых элементов. В этой ситуации замените VerticalStackLayout элементом Grid.
Горизонтальный список
В XAML его элементы могут отображаться в горизонтальном списке, CollectionView задав для свойства значение ItemsLayout
HorizontalList
:
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Кроме того, этот макет можно выполнить, задав ItemsLayout
ItemsLayoutOrientation
Horizontal
свойство LinearItemsLayout
объекту, указав элемент перечисления в качестве Orientation
значения свойства:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Horizontal
};
Это приводит к созданию одного списка строк, который увеличивается горизонтально по мере добавления новых элементов:
Вертикальная сетка
В XAML элементы могут отображаться в вертикальной сетке, CollectionView задав для свойства значение ItemsLayout
VerticalGrid
:
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="VerticalGrid, 2">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Кроме того, этот макет можно выполнить, задав свойство GridItemsLayout
объектуItemsLayout
, свойству которого Orientation
присвоено Vertical
значение :
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
};
По умолчанию вертикали GridItemsLayout
будут отображать элементы в одном столбце. Однако в этом примере свойство имеет GridItemsLayout.Span
значение 2. Это приводит к созданию сетки с двумя столбцами по вертикали по мере добавления новых элементов:
Горизонтальная сетка
В XAML элемент может отображать свои элементы в горизонтальной сетке, CollectionView задав для свойства значение ItemsLayout
HorizontalGrid
:
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="HorizontalGrid, 4">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Кроме того, этот макет можно выполнить, задав свойство GridItemsLayout
объектуItemsLayout
, свойству которого Orientation
присвоено Horizontal
значение :
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal"
Span="4" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(4, ItemsLayoutOrientation.Horizontal)
};
По умолчанию горизонтальное GridItemsLayout
отображение элементов в одной строке. Однако в этом примере свойство имеет GridItemsLayout.Span
значение 4. Это приводит к тому, что сетка с четырьмя строками растет горизонтально по мере добавления новых элементов:
Колонтитулы
CollectionView может представлять верхний и нижний колонтитул, прокручиваемый элементами в списке. Верхний и нижний колонтитул могут быть строками, представлениями или DataTemplate объектами.
CollectionView определяет следующие свойства для указания верхнего и нижнего колонтитула:
Header
object
Тип , указывает строку, привязку или представление, которое будет отображаться в начале списка.HeaderTemplate
, тип DataTemplate, указывает DataTemplate , что используется для форматированияHeader
.Footer
object
Тип , указывает строку, привязку или представление, которое будет отображаться в конце списка.FooterTemplate
, тип DataTemplate, указывает DataTemplate , что используется для форматированияFooter
.
Эти свойства поддерживаются BindableProperty объектами, что означает, что свойства могут быть целевыми объектами привязки данных.
При добавлении заголовка в макет, который растет по горизонтали, слева направо, заголовок отображается слева от списка. Аналогичным образом, когда нижний колонтитул добавляется в макет, который растет горизонтально слева направо, нижний колонтитул отображается справа от списка.
Отображение строк в верхнем и нижнем колонтитуле
Значения Header
и Footer
свойства можно задать string
, как показано в следующем примере:
<CollectionView ItemsSource="{Binding Monkeys}"
Header="Monkeys"
Footer="2019">
...
</CollectionView>
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
Header = "Monkeys",
Footer = "2019"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
Этот код приводит к следующим снимкам экрана: заголовок, показанный на снимке экрана iOS, и нижний колонтитул, показанный на снимке экрана Android:
Отображение представлений в верхнем и нижнем колонтитуле
Для Header
каждого Footer
свойства можно задать представление. Это может быть одно представление или представление, содержащее несколько дочерних представлений. В следующем примере показаны Header
свойства каждого Footer
набора StackLayout для объекта, содержащего Label объект:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.Header>
<StackLayout BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Monkeys"
FontSize="12"
FontAttributes="Bold" />
</StackLayout>
</CollectionView.Header>
<CollectionView.Footer>
<StackLayout BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Friends of Xamarin Monkey"
FontSize="12"
FontAttributes="Bold" />
</StackLayout>
</CollectionView.Footer>
...
</CollectionView>
Эквивалентный код на C# выглядит так:
StackLayout headerStackLayout = new StackLayout();
header.StackLayout.Add(new Label { Text = "Monkeys", ... } );
StackLayout footerStackLayout = new StackLayout();
footerStackLayout.Add(new Label { Text = "Friends of Xamarin Monkey", ... } );
CollectionView collectionView = new CollectionView
{
Header = headerStackLayout,
Footer = footerStackLayout
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
Этот код приводит к следующим снимкам экрана: заголовок, показанный на снимке экрана iOS, и нижний колонтитул, показанный на снимке экрана Android:
Отображение шаблона верхнего и нижнего колонтитула
FooterTemplate
Свойства HeaderTemplate
можно задать для DataTemplate объектов, которые используются для форматирования верхнего и нижнего колонтитулов. В этом сценарии Header
Footer
свойства должны привязаться к текущему источнику для применения шаблонов, как показано в следующем примере:
<CollectionView ItemsSource="{Binding Monkeys}"
Header="{Binding .}"
Footer="{Binding .}">
<CollectionView.HeaderTemplate>
<DataTemplate>
<StackLayout BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Monkeys"
FontSize="12"
FontAttributes="Bold" />
</StackLayout>
</DataTemplate>
</CollectionView.HeaderTemplate>
<CollectionView.FooterTemplate>
<DataTemplate>
<StackLayout BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Friends of Xamarin Monkey"
FontSize="12"
FontAttributes="Bold" />
</StackLayout>
</DataTemplate>
</CollectionView.FooterTemplate>
...
</CollectionView>
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
HeaderTemplate = new DataTemplate(() =>
{
return new StackLayout { };
}),
FooterTemplate = new DataTemplate(() =>
{
return new StackLayout { };
})
};
collectionView.SetBinding(ItemsView.HeaderProperty, ".");
collectionView.SetBinding(ItemsView.FooterProperty, ".");
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
Этот код приводит к следующим снимкам экрана: заголовок, показанный на снимке экрана iOS, и нижний колонтитул, показанный на снимке экрана Android:
Интервалы элементов
По умолчанию между каждым элементом в элементе CollectionViewнет места. Это поведение можно изменить, задав свойства в макете элементов, используемом этим элементом CollectionView.
CollectionView Если свойство присваивается ItemsLayout
LinearItemsLayout
объекту, LinearItemsLayout.ItemSpacing
это свойство можно задать значениеdouble
, представляющее пространство между элементами:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Примечание.
Свойство LinearItemsLayout.ItemSpacing
имеет набор обратного вызова проверки, который гарантирует, что значение свойства всегда больше или равно 0.
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
{
ItemSpacing = 20
}
};
Этот код приводит к вертикальному списку столбцов с интервалом от 20 между элементами:
CollectionView Если свойство GridItemsLayout
ItemsLayout
присваивается объекту, значения и GridItemsLayout.HorizontalItemSpacing
свойства можно задать для double
значений, GridItemsLayout.VerticalItemSpacing
представляющих пустое пространство по вертикали и горизонтально между элементами:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2"
VerticalItemSpacing="20"
HorizontalItemSpacing="30" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Примечание.
GridItemsLayout.HorizontalItemSpacing
Свойства GridItemsLayout.VerticalItemSpacing
имеют набор обратных вызовов проверки, что гарантирует, что значения свойств всегда больше или равно 0.
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
{
VerticalItemSpacing = 20,
HorizontalItemSpacing = 30
}
};
Этот код приводит к вертикальной двухколоночной сетке с вертикальным интервалом между элементами и горизонтальным интервалом от 30 между элементами:
Размер элемента
По умолчанию каждый элемент в объекте CollectionView измеряется по отдельности и размер, при условии, что элементы пользовательского интерфейса в элементе DataTemplate не указывают фиксированные размеры. Это поведение, которое может быть изменено, определяется значением CollectionView.ItemSizingStrategy
свойства. Это значение свойства можно задать одному из ItemSizingStrategy
элементов перечисления:
MeasureAllItems
— каждый элемент измеряется по отдельности. Это значение по умолчанию.MeasureFirstItem
— измеряется только первый элемент, причем все последующие элементы получают тот же размер, что и первый элемент.
Внимание
Стратегия MeasureFirstItem
изменения размера приведет к увеличению производительности при использовании в ситуациях, когда размер элемента предназначен для единообразия во всех элементах.
В следующем примере кода показано задание ItemSizingStrategy
свойства:
<CollectionView ...
ItemSizingStrategy="MeasureFirstItem">
...
</CollectionView>
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
...
ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem
};
Динамическое изменение размера элементов
Элементы в объекте CollectionView могут динамически изменяться во время выполнения путем изменения связанных с макетом свойств элементов в пределах среды DataTemplateвыполнения. Например, следующий пример кода изменяет HeightRequest и WidthRequest свойства Image объекта:
void OnImageTapped(object sender, EventArgs e)
{
Image image = sender as Image;
image.HeightRequest = image.WidthRequest = image.HeightRequest.Equals(60) ? 100 : 60;
}
Обработчик OnImageTapped
событий выполняется в ответ на Image касания объекта и изменяет размеры изображения таким образом, чтобы его было проще просматривать:
Макет справа налево
CollectionView может макетировать содержимое в направлении потока справа налево, задав для свойства значение FlowDirection
RightToLeft
. FlowDirection
Однако свойство в идеале должно быть задано на странице или корневом макете, что приводит ко всем элементам страницы или корневому макету для реагирования на направление потока:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CollectionViewDemos.Views.VerticalListFlowDirectionPage"
Title="Vertical list (RTL FlowDirection)"
FlowDirection="RightToLeft">
<Grid Margin="20">
<CollectionView ItemsSource="{Binding Monkeys}">
...
</CollectionView>
</Grid>
</ContentPage>
Значение по умолчанию FlowDirection
для элемента с родительским MatchParent
элементом . Поэтому значение CollectionView свойства наследуется FlowDirection
от Gridзначения, которое, в свою очередь, наследует FlowDirection
значение свойства от ContentPage. Это приводит к отображению макета справа налево на следующем снимке экрана:
Дополнительные сведения о направлении потока см. в разделе "Справа налево".