Xamarin.Forms Datos collectionView
CollectionView
incluye las siguientes propiedades que definen los datos que se van a mostrar y su apariencia:
ItemsSource
, de tipoIEnumerable
, especifica la colección de elementos que se van a mostrar y tiene un valor predeterminado denull
.ItemTemplate
, de tipoDataTemplate
, especifica la plantilla que se va a aplicar a cada elemento de la colección de elementos que se van a mostrar.
Estas propiedades están respaldadas por BindableProperty
objetos , lo que significa que las propiedades pueden ser destinos de enlaces de datos.
Nota
CollectionView
define una ItemsUpdatingScrollMode
propiedad que representa el comportamiento de desplazamiento de CollectionView
cuando se agregan nuevos elementos a ella. Para obtener más información sobre esta propiedad, vea Control de la posición de desplazamiento cuando se agregan nuevos elementos.
CollectionView
admite la virtualización de datos incremental a medida que el usuario se desplaza. Para más información, consulte Carga incremental de datos.
Rellenar un CollectionView con datos
Se CollectionView
rellena con datos estableciendo su ItemsSource
propiedad en cualquier colección que implemente IEnumerable
. De forma predeterminada, CollectionView
muestra los elementos de una lista vertical.
Importante
CollectionView
Si es necesario actualizar a medida que se agregan, quitan o cambian elementos en la colección subyacente, la colección subyacente debe ser una IEnumerable
colección que envíe notificaciones de cambio de propiedad, como ObservableCollection
.
CollectionView
se puede rellenar con datos mediante el enlace de datos para enlazar su ItemsSource
propiedad a una IEnumerable
colección. En XAML, esto se logra con la Binding
extensión de marcado:
<CollectionView ItemsSource="{Binding Monkeys}" />
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
En este ejemplo, los ItemsSource
datos de propiedad se enlazan a la Monkeys
propiedad del modelo de vista conectado.
Nota
Los enlaces compilados se pueden habilitar para mejorar el rendimiento del enlace de datos en Xamarin.Forms las aplicaciones. Para obtener más información, vea Enlaces compilados.
Para obtener información sobre cómo cambiar el CollectionView
diseño, vea Xamarin.Forms CollectionView Layout. Para obtener información sobre cómo definir la apariencia de cada elemento en CollectionView
, vea Definir apariencia de elemento. Para obtener más información sobre el enlace de datos, consulte Enlace de datos de Xamarin.Forms.
Advertencia
CollectionView
producirá una excepción si ItemsSource
se actualiza fuera del subproceso de la interfaz de usuario.
Definir la apariencia del elemento
La apariencia de cada elemento de se puede definir estableciendo la CollectionView.ItemTemplate
propiedad en CollectionView
:DataTemplate
<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>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
collectionView.ItemTemplate = new DataTemplate(() =>
{
Grid grid = new Grid { Padding = 10 };
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
Image image = new Image { Aspect = Aspect.AspectFill, HeightRequest = 60, WidthRequest = 60 };
image.SetBinding(Image.SourceProperty, "ImageUrl");
Label nameLabel = new Label { FontAttributes = FontAttributes.Bold };
nameLabel.SetBinding(Label.TextProperty, "Name");
Label locationLabel = new Label { FontAttributes = FontAttributes.Italic, VerticalOptions = LayoutOptions.End };
locationLabel.SetBinding(Label.TextProperty, "Location");
Grid.SetRowSpan(image, 2);
grid.Children.Add(image);
grid.Children.Add(nameLabel, 1, 0);
grid.Children.Add(locationLabel, 1, 1);
return grid;
});
Los elementos especificados en define DataTemplate
la apariencia de cada elemento de la lista. En el ejemplo, el diseño dentro DataTemplate
de se administra mediante .Grid
Grid
contiene un Image
objeto y dos Label
objetos que se enlazan a las propiedades de la Monkey
clase :
public class Monkey
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string ImageUrl { get; set; }
}
En las capturas de pantalla siguientes se muestra el resultado de la creación de plantillas de cada elemento de la lista:
Para obtener más información sobre las plantillas de datos, consulte Plantillas de datos de Xamarin.Forms.
Elegir la apariencia del elemento en tiempo de ejecución
La apariencia de cada elemento de se puede elegir en CollectionView
tiempo de ejecución, en función del valor del elemento, estableciendo la CollectionView.ItemTemplate
propiedad en un DataTemplateSelector
objeto :
<ContentPage ...
xmlns:controls="clr-namespace:CollectionViewDemos.Controls">
<ContentPage.Resources>
<DataTemplate x:Key="AmericanMonkeyTemplate">
...
</DataTemplate>
<DataTemplate x:Key="OtherMonkeyTemplate">
...
</DataTemplate>
<controls:MonkeyDataTemplateSelector x:Key="MonkeySelector"
AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
</ContentPage.Resources>
<CollectionView ItemsSource="{Binding Monkeys}"
ItemTemplate="{StaticResource MonkeySelector}" />
</ContentPage>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
ItemTemplate = new MonkeyDataTemplateSelector { ... }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
La ItemTemplate
propiedad se establece en un MonkeyDataTemplateSelector
objeto . En el ejemplo siguiente se muestra la clase MonkeyDataTemplateSelector
:
public class MonkeyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate AmericanMonkey { get; set; }
public DataTemplate OtherMonkey { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return ((Monkey)item).Location.Contains("America") ? AmericanMonkey : OtherMonkey;
}
}
La MonkeyDataTemplateSelector
clase define las AmericanMonkey
propiedades y OtherMonkey
DataTemplate
que se establecen en diferentes plantillas de datos. La OnSelectTemplate
invalidación devuelve la AmericanMonkey
plantilla, que muestra el nombre y la ubicación del mono en teal, cuando el nombre del mono contiene "America". Cuando el nombre del mono no contiene "America", la OnSelectTemplate
invalidación devuelve la OtherMonkey
plantilla, que muestra el nombre y la ubicación del mono en plata:
Para obtener más información sobre los selectores de plantillas de datos, vea Crear un dataTemplateSelectorXamarin.Forms.
Importante
Cuando se usa CollectionView
, nunca establezca el elemento raíz de los DataTemplate
objetos en .ViewCell
Esto provocará una excepción que se produce porque CollectionView
no tiene ningún concepto de celdas.
Menús contextuales
CollectionView
admite menús contextuales para elementos de datos a través SwipeView
de , que revela el menú contextual con un gesto de deslizar el dedo. SwipeView
es un control de contenedor que se ajusta alrededor de un elemento de contenido y proporciona elementos de menú contextual para ese elemento de contenido. Por lo tanto, los menús contextuales se implementan para mediante CollectionView
la creación de un SwipeView
objeto que define el contenido que SwipeView
se ajusta y los elementos del menú contextual que se muestran mediante el gesto de deslizar el dedo. Esto se logra estableciendo como SwipeView
la vista raíz en que DataTemplate
define la apariencia de cada elemento de datos en :CollectionView
<CollectionView x:Name="collectionView"
ItemsSource="{Binding Monkeys}">
<CollectionView.ItemTemplate>
<DataTemplate>
<SwipeView>
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="Favorite"
IconImageSource="favorite.png"
BackgroundColor="LightGreen"
Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.FavoriteCommand}"
CommandParameter="{Binding}" />
<SwipeItem Text="Delete"
IconImageSource="delete.png"
BackgroundColor="LightPink"
Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.DeleteCommand}"
CommandParameter="{Binding}" />
</SwipeItems>
</SwipeView.LeftItems>
<Grid BackgroundColor="White"
Padding="10">
<!-- Define item appearance -->
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
collectionView.ItemTemplate = new DataTemplate(() =>
{
// Define item appearance
Grid grid = new Grid { Padding = 10, BackgroundColor = Color.White };
// ...
SwipeView swipeView = new SwipeView();
SwipeItem favoriteSwipeItem = new SwipeItem
{
Text = "Favorite",
IconImageSource = "favorite.png",
BackgroundColor = Color.LightGreen
};
favoriteSwipeItem.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.FavoriteCommand", source: collectionView));
favoriteSwipeItem.SetBinding(MenuItem.CommandParameterProperty, ".");
SwipeItem deleteSwipeItem = new SwipeItem
{
Text = "Delete",
IconImageSource = "delete.png",
BackgroundColor = Color.LightPink
};
deleteSwipeItem.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.DeleteCommand", source: collectionView));
deleteSwipeItem.SetBinding(MenuItem.CommandParameterProperty, ".");
swipeView.LeftItems = new SwipeItems { favoriteSwipeItem, deleteSwipeItem };
swipeView.Content = grid;
return swipeView;
});
En este ejemplo, el SwipeView
contenido es un Grid
objeto que define la apariencia de cada elemento de .CollectionView
Los elementos de deslizar el dedo se usan para realizar acciones en el SwipeView
contenido y se revelan cuando el control se desliza desde el lado izquierdo:
SwipeView
admite cuatro direcciones de deslizamiento diferentes, con la dirección de deslizamiento definida por la colección direccional SwipeItems
a la que se agregan los SwipeItems
objetos. De forma predeterminada, se ejecuta un elemento de deslizar el dedo cuando el usuario lo pulsa. Además, una vez que se ha ejecutado un elemento de deslizar el dedo, los elementos de deslizar el dedo se ocultan y se vuelve a mostrar el SwipeView
contenido. Sin embargo, estos comportamientos se pueden cambiar.
Para obtener más información sobre el SwipeView
control, vea Xamarin.Forms SwipeView.
Extraer para actualizar
CollectionView
admite la función de extracción para actualizar a través RefreshView
de , que permite que los datos que se muestran se actualicen mediante la extracción en la lista de elementos. RefreshView
es un control de contenedor que proporciona la función de extracción para actualizar a su elemento secundario, siempre que el elemento secundario admita contenido desplazable. Por lo tanto, la extracción para actualizar se implementa para establecerla CollectionView
como elemento secundario de :RefreshView
<RefreshView IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<CollectionView ItemsSource="{Binding Animals}">
...
</CollectionView>
</RefreshView>
El código de C# equivalente es el siguiente:
RefreshView refreshView = new RefreshView();
ICommand refreshCommand = new Command(() =>
{
// IsRefreshing is true
// Refresh data here
refreshView.IsRefreshing = false;
});
refreshView.Command = refreshCommand;
CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
refreshView.Content = collectionView;
// ...
Cuando el usuario inicia una actualización, se ejecuta el ICommand
definido por la Command
propiedad , que debe actualizar los elementos que se muestran. Se muestra una visualización de actualización mientras se produce la actualización, que consta de un círculo de progreso animado:
El valor de la RefreshView.IsRefreshing
propiedad indica el estado actual de RefreshView
. Cuando el usuario desencadena una actualización, esta propiedad pasará automáticamente a true
. Una vez completada la actualización, debe restablecer la propiedad a false
.
Para obtener más información sobre RefreshView
, vea Xamarin.Forms RefreshView.
Carga incremental de datos
CollectionView
admite la virtualización de datos incremental a medida que el usuario se desplaza. Esto permite escenarios como cargar de forma asincrónica una página de datos desde un servicio web, a medida que el usuario se desplaza. Además, el punto en el que se cargan más datos es configurable para que los usuarios no vean espacio en blanco o que se detengan del desplazamiento.
CollectionView
define las siguientes propiedades para controlar la carga incremental de datos:
RemainingItemsThreshold
, de tipoint
, el umbral de los elementos que aún no están visibles en la lista en la que se desencadenará elRemainingItemsThresholdReached
evento.RemainingItemsThresholdReachedCommand
, de tipoICommand
, que se ejecuta cuando se alcanza .RemainingItemsThreshold
RemainingItemsThresholdReachedCommandParameter
, de tipoobject
, que es el parámetro que se pasa aRemainingItemsThresholdReachedCommand
.
CollectionView
también define un RemainingItemsThresholdReached
evento que se desencadena cuando CollectionView
se desplaza lo suficientemente lejos como para que RemainingItemsThreshold
no se muestren los elementos. Este evento se puede controlar para cargar más elementos. Además, cuando se desencadena el RemainingItemsThresholdReached
evento , RemainingItemsThresholdReachedCommand
se ejecuta , lo que permite que la carga incremental de datos tenga lugar en un modelo de vista.
El valor predeterminado de la RemainingItemsThreshold
propiedad es -1, lo que indica que el RemainingItemsThresholdReached
evento nunca se desencadenará. Cuando el valor de la propiedad es 0, el RemainingItemsThresholdReached
evento se activará cuando se muestre el elemento final de .ItemsSource
En el caso de los valores mayores que 0, el RemainingItemsThresholdReached
evento se activará cuando ItemsSource
contenga ese número de elementos a los que aún no se ha desplazado.
Nota
CollectionView
valida la RemainingItemsThreshold
propiedad para que su valor sea siempre mayor o igual que -1.
En el ejemplo XAML siguiente se muestra un CollectionView
objeto que carga los datos de forma incremental:
<CollectionView ItemsSource="{Binding Animals}"
RemainingItemsThreshold="5"
RemainingItemsThresholdReached="OnCollectionViewRemainingItemsThresholdReached">
...
</CollectionView>
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
RemainingItemsThreshold = 5
};
collectionView.RemainingItemsThresholdReached += OnCollectionViewRemainingItemsThresholdReached;
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
En este ejemplo de código, el RemainingItemsThresholdReached
evento se desencadena cuando todavía hay cinco elementos a los que no se ha desplazado y, en respuesta, ejecuta el OnCollectionViewRemainingItemsThresholdReached
controlador de eventos:
void OnCollectionViewRemainingItemsThresholdReached(object sender, EventArgs e)
{
// Retrieve more data here and add it to the CollectionView's ItemsSource collection.
}
Nota
Los datos también se pueden cargar de forma incremental enlazando a RemainingItemsThresholdReachedCommand
una ICommand
implementación en el modelo de vista.