Xamarin.Forms Datos collectionView

Descargar ejemploDescargar el ejemplo

CollectionView incluye las siguientes propiedades que definen los datos que se van a mostrar y su apariencia:

  • ItemsSource, de tipo IEnumerable, especifica la colección de elementos que se van a mostrar y tiene un valor predeterminado de null.
  • ItemTemplate, de tipo DataTemplate, 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:

Elementos con plantilla Captura de pantalla de CollectionView en la que cada elemento está con plantilla, en elementos con plantilla de iOS y Android

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 OtherMonkeyDataTemplate 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:

colecciónView Captura de pantalla de la selección de plantilla de elemento en tiempo de ejecución CollectionView, en la selección de plantilla de elemento en tiempo de ejecución de iOS y Android

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 SwipeViewde , 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:

Captura de pantalla de elementos del menú contextual CollectionView, en iOS y Android

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 RefreshViewde , 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:

Captura de pantalla de CollectionView pull-to-refresh, en iOS y Android

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 tipo int, el umbral de los elementos que aún no están visibles en la lista en la que se desencadenará el RemainingItemsThresholdReached evento.
  • RemainingItemsThresholdReachedCommand, de tipo ICommand, que se ejecuta cuando se alcanza .RemainingItemsThreshold
  • RemainingItemsThresholdReachedCommandParameter, de tipo object, que es el parámetro que se pasa a RemainingItemsThresholdReachedCommand.

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.