Xamarin.Forms CollectionView Dados

CollectionView Inclui as seguintes propriedades que definem os dados a serem exibidos e sua aparência:

  • ItemsSource, do tipo IEnumerable, especifica a coleção de itens a serem exibidos e tem um valor padrão de null.
  • ItemTemplate, do tipo DataTemplate, especifica o modelo a ser aplicado a cada item na coleção de itens a serem exibidos.

Essas propriedades são apoiadas por BindableProperty objetos, o que significa que as propriedades podem ser destinos de associações de dados.

Observação

CollectionView Define uma ItemsUpdatingScrollMode propriedade que representa o comportamento de rolagem do CollectionView quando novos itens são adicionados a ela. Para obter mais informações sobre essa propriedade, consulte Controlar a posição de rolagem quando novos itens são adicionados.

CollectionView Oferece suporte à virtualização de dados incrementais à medida que o usuário rola. Para obter mais informações, consulte Carregar dados incrementalmente.

Preencher um CollectionView com dados

A CollectionView é preenchido com dados definindo sua ItemsSource propriedade para qualquer coleção que implementa IEnumerableo . Por padrão, CollectionView exibe itens em uma lista vertical.

Importante

Se for necessário atualizar à medida que os CollectionView itens são adicionados, removidos ou alterados na coleção subjacente, a coleção subjacente deve ser uma IEnumerable coleção que envia notificações de alteração de propriedade, como ObservableCollection.

CollectionView pode ser preenchido com dados usando a vinculação de dados para vincular sua ItemsSource propriedade a uma IEnumerable coleção. Em XAML, isso é obtido com a Binding extensão de marcação:

<CollectionView ItemsSource="{Binding Monkeys}" />

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Neste exemplo, os ItemsSource dados da propriedade se vinculam à Monkeys propriedade do modelo de exibição conectado.

Observação

As associações compiladas podem ser habilitadas para melhorar o desempenho da vinculação de dados em Xamarin.Forms aplicativos. Para obter mais informações, confira Associações compiladas do Xamarin.Forms.

Para obter informações sobre como alterar o CollectionView layout, consulte Xamarin.Forms CollectionView Layout. Para obter informações sobre como definir a aparência de cada item no , consulte Definir a aparência do CollectionViewitem. Para obter mais informações sobre vinculação de dados, consulte Xamarin.Forms Vinculação de dados.

Aviso

CollectionView lançará uma exceção se ela ItemsSource for atualizada fora do thread da interface do usuário.

Definir a aparência do item

A aparência de cada item no CollectionView pode ser definida definindo a CollectionView.ItemTemplate propriedade como um 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>

Este é o código C# equivalente:

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;
});

Os elementos especificados no DataTemplate definem a aparência de cada item na lista. No exemplo, o layout dentro do DataTemplate é gerenciado por um Gridarquivo . O Grid contém um Image objeto e dois Label objetos que se ligam às propriedades da Monkey classe:

public class Monkey
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string ImageUrl { get; set; }
}

As capturas de tela a seguir mostram o resultado da modelagem de cada item na lista:

Captura de tela do CollectionView onde cada item é modelado, no iOS e Android

Para obter mais informações sobre modelos de dados, consulte Xamarin.Forms Modelos de dados.

Escolher a aparência do item em tempo de execução

A aparência de cada item no pode ser escolhida em CollectionView tempo de execução, com base no valor do item, definindo a CollectionView.ItemTemplate propriedade como um 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>

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView
{
    ItemTemplate = new MonkeyDataTemplateSelector { ... }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

A ItemTemplate propriedade é definida como um MonkeyDataTemplateSelector objeto. O exemplo a seguir mostra a classe 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;
    }
}

A classe MonkeyDataTemplateSelector define as propriedades AmericanMonkey e OtherMonkey do DataTemplate como modelos de dados diferentes. A OnSelectTemplate substituição retorna o AmericanMonkey modelo, que exibe o nome e a localização do macaco em teal, quando o nome do macaco contém "América". Quando o nome do macaco não contém "América", a OnSelectTemplate substituição retorna o OtherMonkey modelo, que exibe o nome e o local do macaco em prata:

Captura de tela da seleção do modelo de item de tempo de execução do CollectionView no iOS e Android

Para obter mais informações sobre seletores de modelo de dados, consulte Criar um Xamarin.Forms DataTemplateSelector.

Importante

Ao usar CollectionViewo , nunca defina o elemento raiz de seus DataTemplate objetos como um ViewCellarquivo . Isso resultará em uma exceção sendo lançada porque CollectionView não tem conceito de células.

Menus de contexto

CollectionView Oferece suporte a menus de contexto para itens de dados por meio do , que revela o menu de contexto com um gesto de passar o SwipeViewdedo. O SwipeView é um controle de contêiner que envolve um item de conteúdo e fornece itens de menu de contexto para esse item de conteúdo. Portanto, os menus de contexto são implementados para um CollectionView criando um SwipeView que define o conteúdo que envolve SwipeView e os itens de menu de contexto que são revelados pelo gesto de passar o dedo. Isso é obtido definindo o SwipeView como a exibição raiz no DataTemplate que define a aparência de cada item de dados no 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>

Este é o código C# equivalente:

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;
});

Neste exemplo, o SwipeView conteúdo é um Grid que define a aparência de cada item no CollectionView. Os itens de passar o SwipeView dedo são usados para executar ações no conteúdo e são revelados quando o controle é deslizado do lado esquerdo:

Captura de tela dos itens do menu de contexto CollectionView no iOS e Android

SwipeView Oferece suporte a quatro direções de deslizamento diferentes, com a direção do gesto de passar o dedo sendo definida pela coleção direcional SwipeItems à qual os SwipeItems objetos são adicionados. Por padrão, um item de passar o dedo é executado quando é tocado pelo usuário. Além disso, depois que um item de passar o dedo é executado, os itens de passar o dedo ficam ocultos e o SwipeView conteúdo é exibido novamente. No entanto, esses comportamentos podem ser alterados.

Para obter mais informações sobre o SwipeView controle, consulte Xamarin.Forms SwipeView.

Deslizar para atualizar

CollectionView Oferece suporte à funcionalidade pull to refresh por meio do RefreshView, que permite que os dados que estão sendo exibidos sejam atualizados puxando para baixo na lista de itens. O RefreshView é um controle de contêiner que fornece funcionalidade pull para atualizar seu filho, desde que o filho ofereça suporte a conteúdo rolável. Portanto, pull to refresh é implementado para um CollectionView definindo-o como o filho de um RefreshView:

<RefreshView IsRefreshing="{Binding IsRefreshing}"
             Command="{Binding RefreshCommand}">
    <CollectionView ItemsSource="{Binding Animals}">
        ...
    </CollectionView>
</RefreshView>

Este é o código C# equivalente:

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;
// ...

Quando o usuário inicia uma atualização, o ICommand definido pela propriedade é executado, o Command que deve atualizar os itens que estão sendo exibidos. Uma visualização de atualização é mostrada enquanto a atualização ocorre, que consiste em um círculo de progresso animado:

Captura de tela do CollectionView pull-to-refresh, no iOS e Android

O valor da RefreshView.IsRefreshing propriedade indica o estado atual do RefreshView. Quando uma atualização é acionada pelo usuário, essa propriedade será automaticamente transferida para true. Quando a atualização for concluída, você deverá redefinir a propriedade para false.

Para obter mais informações sobre RefreshViewo , consulte Xamarin.Forms RefreshView.

Carregar dados incrementalmente

CollectionView Oferece suporte à virtualização de dados incrementais à medida que o usuário rola. Isso permite cenários como carregar de forma assíncrona uma página de dados de um serviço Web, à medida que o usuário rola. Além disso, o ponto em que mais dados são carregados é configurável para que os usuários não vejam espaço em branco ou sejam impedidos de rolar.

CollectionView define as seguintes propriedades para controlar o carregamento incremental de dados:

  • RemainingItemsThreshold, do tipo int, o limite de itens ainda não visíveis na lista na qual o RemainingItemsThresholdReached evento será disparado.
  • RemainingItemsThresholdReachedCommand, do tipo ICommand, que é executado quando o RemainingItemsThreshold é atingido.
  • RemainingItemsThresholdReachedCommandParameter, do tipo object, que é o parâmetro passado para RemainingItemsThresholdReachedCommand.

CollectionViewtambém define um RemainingItemsThresholdReached evento que é acionado quando o é rolado longe o suficiente para que RemainingItemsThreshold os CollectionView itens não tenham sido exibidos. Esse evento pode ser manipulado para carregar mais itens. Além disso, quando o RemainingItemsThresholdReached evento é acionado, o é executado, permitindo que o RemainingItemsThresholdReachedCommand carregamento incremental de dados ocorra em um viewmodel.

O valor padrão da RemainingItemsThreshold propriedade é -1, que indica que o RemainingItemsThresholdReached evento nunca será acionado. Quando o valor da propriedade for 0, o RemainingItemsThresholdReached evento será acionado quando o item final no ItemsSource for exibido. Para valores maiores que 0, o RemainingItemsThresholdReached evento será acionado quando o ItemsSource contém esse número de itens ainda não rolados.

Observação

CollectionView valida a RemainingItemsThreshold propriedade para que seu valor seja sempre maior ou igual a -1.

O exemplo XAML a seguir mostra um CollectionView que carrega dados incrementalmente:

<CollectionView ItemsSource="{Binding Animals}"
                RemainingItemsThreshold="5"
                RemainingItemsThresholdReached="OnCollectionViewRemainingItemsThresholdReached">
    ...
</CollectionView>

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView
{
    RemainingItemsThreshold = 5
};
collectionView.RemainingItemsThresholdReached += OnCollectionViewRemainingItemsThresholdReached;
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");

Neste exemplo de código, o RemainingItemsThresholdReached evento é acionado quando há 5 itens ainda não rolados e, em resposta, executa o OnCollectionViewRemainingItemsThresholdReached manipulador de eventos:

void OnCollectionViewRemainingItemsThresholdReached(object sender, EventArgs e)
{
    // Retrieve more data here and add it to the CollectionView's ItemsSource collection.
}

Observação

Os dados também podem ser carregados incrementalmente vinculando o RemainingItemsThresholdReachedCommand a uma ICommand implementação no viewmodel.