Xamarin Forms  -  CollectionView Básico - II
 Neste artigo vou apresentar o novo recurso CollectionView da versão 4.0 do Xamarin Forms.

Continuando a primeira parte do artigo veremos como podemos selecionar um item na CollectionView.

Para controlar a seleção de um item a CollectionView define as seguintes propriedades:

- SelectionMode, do tipo SelectionMode , define o modo de seleção.

- SelectedItem, do tipo object, define o item selecionado na lista. Essa propriedade tem um modo de associação padrão de TwoWay, e tem um null valor quando nenhum item está selecionado.

- SelectedItems, do tipo IList<object>, define os itens selecionados na lista. Essa propriedade tem um modo de associação padrão OneWay, e tem um valor null quando nenhum item estiver selecionado.

- SelectionChangedCommand, do tipo ICommand, que é executado quando o item selecionado for alterado.

- SelectionChangedCommandParameter, do tipo object, que é o parâmetro que é passado para o SelectionChangedCommand.

Por padrão, a seleção de itens na CollectionView está desabilitada. Para alterar esse comportamento podemos definir o valor da propriedade SelectionMode como :

- None – indica que os itens não podem ser selecionados. Este é o valor padrão.
- Single – indica que um único item pode ser selecionado, com o item selecionado sendo realçado.
- Multiple – indica que vários itens podem ser selecionados, com os itens selecionados sendo realçados.

Além disso a CollectionView define o evento SelectionChanged que é disparado quando o a propriedade SelectedItem for alterada, seja porque o usuário selecionou um item da lista, ou quando um aplicativo define a propriedade.

Além disso, esse evento também é disparado quando a propriedade SelectedItems muda. O objeto SelectionChangedEventArgs que acompanha o evento SelectionChanged tem duas propriedades, ambos do tipo IReadOnlyList<object>:

- PreviousSelection – a lista de itens que foram selecionados, antes que a seleção foi alterada;
- CurrentSelection – a lista de itens que são selecionados, após a seleção ser alterada;

Realizando uma seleção única no CollectionView

Quando a propriedade SelectionMode estiver definida como Single, podemos selecionar um único item no CollectionView.  Quando um item for selecionado, a propriedade SelectedItem será definida como o valor do item selecionado.

Quando essa propriedade for alterada, o SelectionChangedCommand é executado (com o valor da SelectionChangedCommandParameter sendo passado para o ICommand) e o evento SelectionChanged é acionado.

O trecho de código a seguir mostra uma CollectionView definda para seleção única:

<CollectionView ItemsSource="{Binding Times}"
                SelectionMode="Single"
                SelectionChanged="OnCollectionViewSelectionChanged">
    ...
</CollectionView>

Neste exemplo o manipulador de eventos OnCollectionViewSelectionChanged é executado quando o evento SelectionChanged é acionado, com o manipulador de eventos retornando o item selecionado anteriormente e a seleção atual do item.

Abaixo um exemplo de código que pode ser usado para obter o item atual e o anterior no evento OnCollectionViewSelectionChanged  :

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string anterior = (e.PreviousSelection.FirstOrDefault() as Time)?.Nome;
    string atual = (e.CurrentSelection.FirstOrDefault() as Time)?.Nome;
    ...
}

Lembrando que o evento SelectionChanged podem ser acionado por alterações que ocorrem como resultado da alteração da propriedade SelecionMode.

Depois dessa teoria vamos para a prática...

Implementando a seleção única na CollectionView

Vamos usar o projeto criado na primeira parte do artigo.

No projeto criado vamos incluir uma pasta chamada Views e nesta pasta incluir uma nova view do tipo Content Page chamada CollectionViewSingleSelectionPage.xaml e incluir o código abaixo nesta view:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="XF_CollectinViewBasico.CollectionViewSingleSelectionPage">
    <ContentPage.Content>
        <StackLayout Margin="20">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Label Text="Seleção anterior : "  TextColor="Red" FontSize="Medium" />
                <Label x:Name="previousSelectedItemLabel" Grid.Column="1"/>
                <Label Grid.Row="1" Text="Seleção atual : " TextColor="Blue" FontSize="Medium"/>
                <Label x:Name="currentSelectedItemLabel" Grid.Row="1"  Grid.Column="1" />
            </Grid>
            <CollectionView ItemsSource="{Binding Times}"
                        SelectionMode="Single"
                        SelectionChanged="OnCollectionViewSelectionChanged">
                <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 ImagemUrl}" 
                               Aspect="AspectFill" HeightRequest="60" 
                               WidthRequest="60" />
                            <Label Grid.Column="1" Text="{Binding Nome}" FontAttributes="Bold" />
                            <Label Grid.Row="1" Grid.Column="1" Text="{Binding Pontos}" 
                                   FontAttributes="Italic" VerticalOptions="End" />
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Este código é praticamente idêntico ao usado na view MainPage.xaml do projeto. A diferença é que estamos definindo a propriedade SelectionMode igual a Single e defindindo o evento SelectionChange que iremos tratar a seguir. Com isso habilitamos a seleção de um único item na CollectionView.

Agora no arquivo CollectionViewSingleSelectionPage.xaml.cs vamos incluir o seguinte código:

using System.Collections.Generic;
using System.Linq;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XF_CollectinViewBasico.Models;
using XF_CollectinViewBasico.ViewModels;

namespace XF_CollectinViewBasico
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class CollectionViewSingleSelectionPage : ContentPage
    {
        public CollectionViewSingleSelectionPage()
        {
            InitializeComponent();
            BindingContext = new TimesViewModel();
            UpdateSelectionData(Enumerable.Empty<Time>(), Enumerable.Empty<Time>());

        }
        void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            UpdateSelectionData(e.PreviousSelection, e.CurrentSelection);
        }

        void UpdateSelectionData(IEnumerable<object> previousSelectedItems, IEnumerable<object> currentSelectedItems)
        {
            string anterior = (previousSelectedItems.FirstOrDefault() as Time)?.Nome;
            string atual = (currentSelectedItems.FirstOrDefault() as Time)?.Nome;
            previousSelectedItemLabel.Text = string.IsNullOrWhiteSpace(anterior) ? "[none]" : anterior;
            currentSelectedItemLabel.Text = string.IsNullOrWhiteSpace(atual) ? "[none]" : atual;
        }
    }
}

Neste código estamos capturando a seleção atual e anterior do usuário na CollectionView e exibindo nas Labels.

Vamos alterar o código do arquivo App.xaml.cs para exibir a view criada neste artigo:

        public App()
        {
            InitializeComponent();
            MainPage = new CollectionViewSingleSelectionPage();
        }

Executando o projeto iremos obter o seguinte resultado:

Na próxima parte do artigo vamos continuar veremos a seleção de mais de um item na CollectionView.

Pegue o código do projeto compartilhado aqui :  XF_CollectinViewBasico_2.zip  (sem as referências)

"Louvai ao Senhor dos senhores; porque a sua benignidade dura para sempre."
Salmos 136:3

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti