Xamarin.Forms Dados CollectionView
CollectionView
Inclui as seguintes propriedades que definem os dados a serem exibidos e sua aparência:
ItemsSource
, do tipoIEnumerable
, especifica a coleção de itens a serem exibidos e tem um valor padrão denull
.ItemTemplate
, do tipoDataTemplate
, especifica o modelo a ser aplicado a cada item na coleção de itens a serem exibidos.
Essas propriedades são apoiadas por objetos BindableProperty
, o que significa que as propriedades podem ser alvos de vinculações de dados.
Observação
CollectionView
define uma propriedade ItemsUpdatingScrollMode
que representa o comportamento de rolagem do CollectionView
quando novos itens são adicionados a ele. Para obter mais informações sobre essa propriedade, veja Controlar a posição de rolagem quando novos itens são adicionados.
CollectionView
oferece suporte à virtualização incremental de dados à medida que o usuário rola. Para obter mais informações, veja Carregar dados de forma incremental.
Preencher um CollectionView com dados
Um CollectionView
é preenchido com dados definindo sua propriedade ItemsSource
para qualquer coleção que implemente IEnumerable
. Por padrão, CollectionView
exibe itens em uma lista vertical.
Importante
Se o CollectionView
for necessário para atualizar conforme os itens são adicionados, removidos ou alterados na coleção subjacente, a coleção subjacente deverá ser uma coleção IEnumerable
que envia notificações de alteração de propriedade, como ObservableCollection
.
CollectionView
pode ser preenchido com dados usando vinculação de dados para vincular sua propriedade ItemsSource
a uma coleção IEnumerable
. No XAML, isso é conseguido com a extensão de marcação Binding
:
<CollectionView ItemsSource="{Binding Monkeys}" />
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
Nesse exemplo, os dados da propriedade ItemsSource
são vinculados à propriedade Monkeys
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 obter mais informações, confira Associações compiladas do Xamarin.Forms.
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 CollectionView
, veja Definir aparência do item. Para obter mais informações sobre a associação de dados, consulte Xamarin.Forms Associação de dados.
Aviso
CollectionView
lançará uma exceção se seu ItemsSource
for atualizado no thread da UI.
Definir a aparência do item
A aparência de cada item no CollectionView
pode ser definida definindo a propriedade CollectionView.ItemTemplate
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 da lista. No exemplo, o layout dentro do DataTemplate
é gerenciado por um Grid
. O Grid
contém um objeto Image
e dois objetos Label
, todos vinculados às propriedades da classe Monkey
:
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:
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 CollectionView
pode ser escolhida em tempo de execução, com base no valor do item, definindo a propriedade CollectionView.ItemTemplate
como um objeto DataTemplateSelector
:
<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 propriedade ItemTemplate
é definida como um objeto MonkeyDataTemplateSelector
. 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 propriedades AmericanMonkey
e OtherMonkey
DataTemplate
que são configuradas para diferentes modelos de dados. A substituição OnSelectTemplate
retorna o modeloAmericanMonkey
, que exibe o nome e a localização do macaco em azul-petróleo, quando o nome do macaco contém "América". Quando o nome do macaco não contém "América", a substituição OnSelectTemplate
retorna o modelo OtherMonkey
, que exibe o nome e a localização do macaco em prata:
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 dos seus objetos DataTemplate
como um ViewCell
. Isso resultará no lançamento de uma exceção 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 SwipeView
, que revela o menu de contexto com um gesto de deslizar. 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
envolve e os itens do menu de contexto que são revelados pelo gesto de deslizar. Isso é conseguido definindo SwipeView
como a visualizaçã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;
});
Nesse exemplo, o SwipeView
conteúdo é um Grid
que define a aparência de cada item no CollectionView
. Os itens de deslizar são usados para executar ações no conteúdo SwipeView
e são revelados quando o controle é deslizado do lado esquerdo:
SwipeView
suporta quatro direções de deslizamento diferentes, com a direção de deslizamento sendo definida pela coleção direcional SwipeItems
à qual os objetos SwipeItems
são adicionados. Por padrão, um item de deslizar é executado quando o usuário toca nele. Além disso, depois que um item de deslizar for executado, os itens de deslizar serão ocultados e o conteúdo SwipeView
será 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
suporta a funcionalidade pull to refresh por meio do RefreshView
, que permite que os dados exibidos sejam atualizados puxando para baixo a lista de itens. O RefreshView
é um controle de contêiner que fornece funcionalidade pull para atualizar para seu filho, desde que o filho suporte conteúdo rolável. Portanto, puxar para atualizar é implementado para um CollectionView
definindo-o como 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 Command
é 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:
O valor da propriedade RefreshView.IsRefreshing
indica o estado atual do RefreshView
. Quando uma atualização é acionada pelo usuário, essa propriedade fará a transição automaticamente para true
. Assim que a atualização for concluída, você deverá redefinir a propriedade para false
.
Para obter mais informações sobre RefreshView
o , consulte Xamarin.Forms RefreshView.
Carregar dados de forma incremental
CollectionView
oferece suporte à virtualização incremental de dados à medida que o usuário rola. Isso permite cenários como o carregamento assíncrono de 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ços em branco ou sejam impedidos de rolar.
CollectionView
define as seguintes propriedades para controlar o carregamento incremental de dados:
RemainingItemsThreshold
, do tipoint
, o limite de itens ainda não visíveis na lista na qual o eventoRemainingItemsThresholdReached
será acionado.RemainingItemsThresholdReachedCommand
, do tipoICommand
, que é executado quando oRemainingItemsThreshold
é alcançado.RemainingItemsThresholdReachedCommandParameter
, do tipoobject
, que é o parâmetro passado paraRemainingItemsThresholdReachedCommand
.
CollectionView
também define um evento RemainingItemsThresholdReached
que é acionado quando o CollectionView
é rolado o suficiente para que RemainingItemsThreshold
os itens não sejam exibidos. Esse evento pode ser tratado para carregar mais itens. Além disso, quando o evento RemainingItemsThresholdReached
é disparado, o RemainingItemsThresholdReachedCommand
é executado, permitindo que o carregamento incremental de dados ocorra em um viewmodel.
O valor padrão da propriedade RemainingItemsThreshold
é -1, o que indica que o evento RemainingItemsThresholdReached
nunca será acionado. Quando o valor da propriedade for 0, o evento RemainingItemsThresholdReached
será acionado quando o item final do ItemsSource
for exibido. Para valores maiores que 0, o evento RemainingItemsThresholdReached
será disparado quando o ItemsSource
contiver aquele número de itens ainda não rolados.
Observação
CollectionView
valida a propriedade RemainingItemsThreshold
para que seu valor seja sempre maior ou igual a -1.
O exemplo XAML a seguir mostra um CollectionView
que carrega dados de forma incremental:
<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");
Nesse exemplo de código, o evento RemainingItemsThresholdReached
é acionado quando há 5 itens ainda não rolados e, em resposta, executa o manipulador de eventos OnCollectionViewRemainingItemsThresholdReached
:
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 de forma incremental vinculando o RemainingItemsThresholdReachedCommand
a uma implementação ICommand
no viewmodel.