Especificar el diseño CollectionView
CollectionView de .NET Multi-platform App UI (.NET MAUI) define las siguientes propiedades que controlan el diseño:
ItemsLayout
, de tipoIItemsLayout
, especifica el diseño que se va a usar:ItemSizingStrategy
, de tipoItemSizingStrategy
, especifica la estrategia de medida de elemento que se va a usar.
Todas estas propiedades están respaldadas por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos.
De forma predeterminada, CollectionView mostrará sus elementos en una lista vertical. Sin embargo, se puede usar cualquiera de los siguientes diseños:
- Lista vertical: una lista de una columna que crece verticalmente a medida que se agregan nuevos elementos.
- Lista horizontal: una lista de una fila que crece horizontalmente a medida que se agregan nuevos elementos.
- Cuadrícula vertical: una cuadrícula de varias columnas que crece verticalmente a medida que se agregan nuevos elementos.
- Cuadrícula horizontal: una cuadrícula de varias filas que crece horizontalmente a medida que se agregan nuevos elementos.
Estos diseños se pueden especificar estableciendo la propiedad ItemsLayout
en la clase que deriva de la clase ItemsLayout
. Esta clase define las propiedades siguientes:
Orientation
, de tipoItemsLayoutOrientation
, especifica la dirección en la que CollectionView se expande a medida que se agregan elementos.SnapPointsAlignment
, de tipoSnapPointsAlignment
, especifica cómo se alinean los puntos de acoplamiento con los elementos.SnapPointsType
, de tipoSnapPointsType
, especifica el comportamiento de los puntos de acoplamiento al desplazarse.
Todas estas propiedades están respaldadas por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos. Para obtener más información sobre los puntos de acoplamiento, consulta Puntos de acoplamiento en Control del desplazamiento en CollectionView.
La enumeración ItemsLayoutOrientation
define los miembros siguientes:
Vertical
indica que CollectionView se expandirá verticalmente a medida que se agregan elementos.Horizontal
indica que CollectionView se expandirá horizontalmente a medida que se agregan elementos.
La clase LinearItemsLayout
hereda de la clase ItemsLayout
y define una propiedad ItemSpacing
, de tipo double
, que representa el espacio vacío alrededor de cada elemento. El valor predeterminado de esta propiedad es 0 y su valor siempre debe ser mayor o igual que 0. La clase LinearItemsLayout
también define los miembros estáticos Vertical
y Horizontal
. Estos miembros se pueden usar para crear listas verticales u horizontales, respectivamente. Como alternativa, se puede crear un objeto LinearItemsLayout
, especificando un miembro de enumeración ItemsLayoutOrientation
como argumento.
Además, la clase GridItemsLayout
hereda de la clase ItemsLayout
y define las siguientes propiedades:
VerticalItemSpacing
, de tipodouble
, que representa el espacio vacío vertical alrededor de cada elemento. El valor predeterminado de esta propiedad es 0 y su valor siempre debe ser mayor o igual que 0.HorizontalItemSpacing
, de tipodouble
, que representa el espacio vacío horizontal alrededor de cada elemento. El valor predeterminado de esta propiedad es 0 y su valor siempre debe ser mayor o igual que 0.Span
, de tipoint
, que representa el número de columnas o filas que se van a mostrar en la cuadrícula. El valor predeterminado de esta propiedad es 1 y su valor siempre debe ser mayor o igual que 1.
Todas estas propiedades están respaldadas por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos.
Nota:
CollectionView usa los motores de diseño nativos para realizar el diseño.
Lista vertical
De forma predeterminada, CollectionView mostrará sus elementos en un diseño de lista vertical. Por lo tanto, no es necesario establecer la propiedad ItemsLayout
para usar este diseño:
<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>
Sin embargo, por integridad, en XAML CollectionView se puede establecer para mostrar sus elementos en una lista vertical estableciendo su propiedad ItemsLayout
en VerticalList
:
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="VerticalList">
...
</CollectionView>
Como alternativa, esto también se puede lograr estableciendo la propiedad ItemsLayout
en un objeto LinearItemsLayout
, especificando el miembro de enumeración Vertical
ItemsLayoutOrientation
como valor de propiedad Orientation
:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
...
</CollectionView>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Vertical
};
Esto da como resultado una lista de una sola columna, que crece verticalmente a medida que se agregan nuevos elementos:
Sugerencia
Colocar un elemento CollectionView dentro de VerticalStackLayout puede detener el desplazamiento de CollectionView y puede limitar el número de elementos que se muestran. En esta situación, reemplaza VerticalStackLayout por Grid.
Lista horizontal
En XAML, CollectionView puede mostrar sus elementos en una lista horizontal estableciendo su propiedad ItemsLayout
en 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>
Como alternativa, este diseño también se puede realizar estableciendo la propiedad ItemsLayout
en un objeto LinearItemsLayout
, especificando el miembro de enumeración Horizontal
ItemsLayoutOrientation
como valor de propiedad Orientation
:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Horizontal
};
Esto da lugar a una sola lista de filas, que crece horizontalmente a medida que se agregan nuevos elementos:
Cuadrícula vertical
En XAML, CollectionView puede mostrar sus elementos en una cuadrícula vertical estableciendo su propiedad ItemsLayout
en 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>
Como alternativa, este diseño también se puede lograr estableciendo la propiedad ItemsLayout
en un objeto GridItemsLayout
cuya propiedad Orientation
está establecida en Vertical
:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
...
</CollectionView>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
};
De forma predeterminada, un objeto GridItemsLayout
vertical mostrará elementos en una sola columna. Sin embargo, este ejemplo establece la propiedad GridItemsLayout.Span
en 2. Esto da lugar a una cuadrícula de dos columnas, que crece verticalmente a medida que se agregan nuevos elementos:
Cuadrícula horizontal
En XAML, CollectionView puede mostrar sus elementos en una cuadrícula horizontal estableciendo su propiedad ItemsLayout
en 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>
Como alternativa, este diseño también se puede lograr estableciendo la propiedad ItemsLayout
en un objeto GridItemsLayout
cuya propiedad Orientation
está establecida en Horizontal
:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal"
Span="4" />
</CollectionView.ItemsLayout>
...
</CollectionView>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(4, ItemsLayoutOrientation.Horizontal)
};
De forma predeterminada, un objeto GridItemsLayout
horizontal mostrará elementos en una sola fila. Sin embargo, este ejemplo establece la propiedad GridItemsLayout.Span
en 4. Esto da lugar a una cuadrícula de cuatro filas, que crece horizontalmente a medida que se agregan nuevos elementos:
Encabezados y pies de página
CollectionView puede presentar un encabezado y pie de página que se desplazan con los elementos de la lista. El encabezado y el pie de página pueden ser cadenas, vistas o objetos DataTemplate.
CollectionView define las siguientes propiedades para especificar el encabezado y el pie de página:
Header
, de tipoobject
, especifica la cadena, el enlace o la vista que se mostrarán al principio de la lista.HeaderTemplate
, de tipo DataTemplate, especifica el DataTemplate que se va a usar para dar formato aHeader
.Footer
, de tipoobject
, especifica la cadena, el enlace o la vista que se mostrarán al final de la lista.FooterTemplate
, de tipo DataTemplate, especifica el DataTemplate que se va a usar para dar formato aFooter
.
Todas estas propiedades están respaldadas por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos.
Cuando se agrega un encabezado a un diseño que crece horizontalmente, de izquierda a derecha, dicho encabezado se muestra a la izquierda de la lista. Del mismo modo, cuando se agrega un pie de página a un diseño que crece horizontalmente, de izquierda a derecha, el pie de página se muestra a la derecha de la lista.
Mostrar cadenas en el encabezado y el pie de página
La propiedad Header
y Footer
se puede establecer en valores string
, como se muestra en el siguiente ejemplo:
<CollectionView ItemsSource="{Binding Monkeys}"
Header="Monkeys"
Footer="2019">
...
</CollectionView>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
Header = "Monkeys",
Footer = "2019"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
Este código da lugar a las capturas de pantalla siguientes, con el encabezado que se muestra en la captura de pantalla de iOS y el pie de página que se muestra en la captura de pantalla de Android:
Mostrar vistas en el encabezado y el pie de página
Las propiedades Header
y Footer
se pueden establecer en una vista. Esto puede ser una sola vista o una vista que contenga varias vistas secundarias. En el siguiente ejemplo, se muestran las propiedades Header
y Footer
, cada una establecida en un objeto StackLayout que contiene un objeto 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>
El código de C# equivalente es el siguiente:
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");
Este código da lugar a las capturas de pantalla siguientes, con el encabezado que se muestra en la captura de pantalla de iOS y el pie de página que se muestra en la captura de pantalla de Android:
Mostrar un encabezado y pie de página con plantilla
Las propiedades HeaderTemplate
y FooterTemplate
se pueden establecer en objetos DataTemplate que se usan para dar formato al encabezado y al pie de página. En este escenario, las propiedades Header
y Footer
deben enlazarse al origen actual de la plantilla que se va a aplicar, como se muestra en el siguiente ejemplo:
<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>
El código de C# equivalente es el siguiente:
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");
Este código da lugar a las capturas de pantalla siguientes, con el encabezado que se muestra en la captura de pantalla de iOS y el pie de página que se muestra en la captura de pantalla de Android:
Espaciado de elementos
De forma predeterminada, no hay ningún espacio entre cada elemento en CollectionView. Este comportamiento se puede cambiar estableciendo propiedades en el diseño de elementos que CollectionView usa.
Cuando CollectionView establece su propiedad ItemsLayout
en un objeto LinearItemsLayout
, la propiedad LinearItemsLayout.ItemSpacing
se puede establecer en un valor double
que representa el espacio entre elementos:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Nota:
La propiedad LinearItemsLayout.ItemSpacing
tiene un conjunto de devolución de llamada de validación, lo que garantiza que el valor de la propiedad sea siempre mayor o igual que 0.
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
{
ItemSpacing = 20
}
};
Este código da como resultado una lista de columnas únicas verticales que tiene un espaciado de 20 entre elementos:
Cuando un CollectionView establece su propiedad ItemsLayout
en un objeto GridItemsLayout
, las propiedades GridItemsLayout.VerticalItemSpacing
y GridItemsLayout.HorizontalItemSpacing
se pueden establecer en double
valores que representan el espacio vacío vertical y horizontalmente entre elementos:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2"
VerticalItemSpacing="20"
HorizontalItemSpacing="30" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Nota:
Las propiedades GridItemsLayout.VerticalItemSpacing
y GridItemsLayout.HorizontalItemSpacing
tienen establecidas devoluciones de llamada de validación, lo que garantiza que los valores de las propiedades sean siempre mayores o iguales que 0.
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
{
VerticalItemSpacing = 20,
HorizontalItemSpacing = 30
}
};
Este código da como resultado una cuadrícula vertical de dos columnas que tiene un espaciado vertical de 20 entre elementos y un espaciado horizontal de 30 entre elementos:
Ajuste de tamaño de elemento
De forma predeterminada, cada elemento de un elemento CollectionView se mide y ajusta individualmente, siempre que los elementos de la interfaz de usuario de DataTemplate no especifiquen tamaños fijos. Este comportamiento, que puede cambiar, se especifica mediante el valor de la propiedad CollectionView.ItemSizingStrategy
. Este valor de la propiedad se puede establecer en uno de los valores de la enumeración ItemSizingStrategy
:
MeasureAllItems
: cada elemento se mide individualmente. Este es el valor predeterminado.MeasureFirstItem
: solo se mide el primer elemento, con todos los elementos subsiguientes a los que se les da el mismo tamaño que el primer elemento.
Importante
La estrategia de dimensionamiento MeasureFirstItem
dará lugar a un mayor rendimiento cuando se usa en situaciones en las que el tamaño del elemento está pensado para ser uniforme en todos los elementos.
En el código de ejemplo siguiente se muestra la propiedad ItemSizingStrategy
:
<CollectionView ...
ItemSizingStrategy="MeasureFirstItem">
...
</CollectionView>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
...
ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem
};
Cambio de tamaño dinámico de los elementos
Los elementos de un CollectionView objeto se pueden cambiar dinámicamente en tiempo de ejecución, cambiando las propiedades relacionadas con el diseño de los elementos dentro de DataTemplate. Por ejemplo, en el ejemplo de código siguiente se cambian las propiedades HeightRequest y WidthRequest de un objeto Image:
void OnImageTapped(object sender, EventArgs e)
{
Image image = sender as Image;
image.HeightRequest = image.WidthRequest = image.HeightRequest.Equals(60) ? 100 : 60;
}
El controlador de eventos OnImageTapped
se ejecuta en respuesta a un objeto Image que se está pulsando y cambia las dimensiones de la imagen para que se vea más fácilmente:
Diseño de derecha a izquierda
CollectionView puede diseñar su contenido en una dirección de flujo de derecha a izquierda estableciendo su propiedad RightToLeft
en FlowDirection
. Sin embargo, la propiedad FlowDirection
debe establecerse idealmente en una página o diseño raíz, lo que hace que todos los elementos de la página o diseño raíz respondan a la dirección del flujo:
<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>
El valor predeterminado FlowDirection
de un elemento con un elemento primario es MatchParent
. Por lo tanto, CollectionView hereda el valor de la propiedad FlowDirection
de Grid, que a su vez hereda el valor de la propiedad FlowDirection
de ContentPage. El resultado es el diseño de derecha a izquierda que se muestra en la captura de pantalla siguiente:
Para obtener más información sobre la dirección del flujo, consulta Localización de derecha a izquierda.