Xamarin.Forms Dados collectionView

Baixar exemplo Baixar o exemplo

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 ele. Para obter mais informações sobre essa propriedade, consulte Controlar a posição de rolagem quando novos itens forem adicionados.

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

Preencher um CollectionView com dados

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

Importante

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

CollectionView pode ser preenchido com dados usando a associação de dados para associar sua ItemsSource propriedade a uma coleção IEnumerable . No 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 dados da ItemsSource propriedade são associados à Monkeys propriedade do viewmodel conectado.

Observação

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

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

Aviso

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

Definir 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 na DataTemplate definem a aparência de cada item na lista. No exemplo, o layout dentro do DataTemplate é gerenciado por um Grid. O Grid contém um Image objeto e dois Label objetos que se associam à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 CollectionView de CollectionView em que cada item é modelo, em itens de modelo do iOS e do Android

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

Escolher a aparência do item no runtime

A aparência de cada item no CollectionView pode ser escolhida em runtime, 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 MonkeyDataTemplateSelector classe define e OtherMonkeyDataTemplate as propriedades definidas AmericanMonkey como modelos de dados diferentes. A OnSelectTemplate substituição retorna o AmericanMonkey modelo, que exibe o nome do macaco e a localização no téal, quando o nome do macaco contém "America". Quando o nome do macaco não contém "América", a OnSelectTemplate substituição retorna o OtherMonkey modelo, que exibe o nome do macaco e a localização em prata:

captura de tela collectionview da seleção de modelo de item de runtime CollectionView, na seleção de modelo de item do iOS e Android

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

Importante

Ao usar CollectionView, nunca defina o elemento raiz de seus DataTemplate objetos como um ViewCell. Isso resultará na geração de uma exceção porque CollectionView não tem nenhum conceito de células.

Menus de contexto

CollectionView dá suporte a menus de contexto para itens de dados por meio do SwipeView, que revela o menu de contexto com um gesto de passar o dedo. 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 o SwipeView encapsula 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 é apagado do lado esquerdo:

Captura de tela dos itens de menu de contexto CollectionView, em iOS e Android

SwipeView dá suporte a quatro direções de passar o dedo diferentes, com a direção do 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 ele é tocado pelo usuário. Além disso, depois que um item de passar o dedo for executado, os itens de passar o dedo ficarão ocultos e o SwipeView conteúdo será exibido novamente. No entanto, esses comportamentos podem ser alterados.

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

Puxar para atualizar

CollectionView dá suporte ao pull para atualizar a funcionalidade 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 pull para atualizar a funcionalidade para seu filho, desde que o filho dê suporte ao conteúdo rolável. Portanto, o pull para atualizar é 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 Command propriedade é executado, o 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:

do CollectionView pull-to-refresh, no iOS e no Android

O valor da RefreshView.IsRefreshing propriedade indica o estado atual do RefreshView. Quando uma atualização é disparada pelo usuário, essa propriedade fará a transição automática para true. Depois que a atualização for concluída, você deverá redefinir a propriedade para false.

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

Carregar dados incrementalmente

CollectionView dá suporte à virtualização incremental de dados à 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, conforme o usuário rola. Além disso, o ponto no qual 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á acionado.
  • RemainingItemsThresholdReachedCommand, do tipo ICommand, que é executado quando o RemainingItemsThreshold é atingido.
  • RemainingItemsThresholdReachedCommandParameter, do tipo object, que é o parâmetro passado para RemainingItemsThresholdReachedCommand.

CollectionView também define um RemainingItemsThresholdReached evento que é acionado quando o CollectionView é rolado para longe o suficiente para que RemainingItemsThreshold os 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 de dados incremental ocorra em um viewmodel.

O valor padrão da RemainingItemsThreshold propriedade é -1, o 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 contiver esse número de itens ainda não rolados para.

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 para 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 associando o RemainingItemsThresholdReachedCommand a uma implementação ICommand no viewmodel.