Xamarin.Forms Seleção de CollectionView

CollectionView define as seguintes propriedades que controlam a seleção de itens:

  • SelectionMode, do tipo SelectionMode, o modo de seleção.
  • SelectedItem, do tipo object, o item selecionado na lista. Essa propriedade tem um modo de vinculação padrão TwoWay e um valor null quando nenhum item estiver selecionado.
  • SelectedItems, do tipo IList<object>, os itens selecionados na lista. Essa propriedade tem um modo de vinculação padrão OneWay e um valor null quando nenhum item estiver selecionado.
  • SelectionChangedCommand, do tipo ICommand, que é executado quando o item selecionado é alterado.
  • SelectionChangedCommandParameter, do tipo object, que é o parâmetro passado para SelectionChangedCommand.

Todas essas propriedades são apoiadas por objetos BindableProperty, o que significa que essas propriedades podem ser o destino de vinculações de dados.

Por padrão, a seleção da CollectionView está desabilitada. No entanto, esse comportamento pode ser alterado ao definir o valor da propriedade SelectionMode para um dos membros da enumeração SelectionMode:

  • 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.

CollectionView define um evento SelectionChanged que é acionado quando a propriedade SelectedItem é alterada, ou devido ao fato de o usuário selecionar um item na lista ou quando um aplicativo define a propriedade. Além disso, esse evento também é acionado quando a propriedade SelectedItems é alterada. O objeto SelectionChangedEventArgs que acompanha o evento SelectionChanged tem duas propriedades, ambas do tipo IReadOnlyList<object>:

  • PreviousSelection — a lista de itens que foram selecionados, antes de a seleção ter sido alterada.
  • CurrentSelection — a lista de itens selecionados após a alteração da seleção.

Além disso, CollectionView tem um método UpdateSelectedItems que atualiza a propriedade SelectedItems com uma lista de itens selecionados, embora dispare apenas uma única notificação de alteração.

Seleção única

Quando a propriedade SelectionMode é definida como Single, um único item no CollectionView pode ser selecionado. Quando um item é selecionado, a propriedade SelectedItem será definida com o valor do item selecionado. Quando essa propriedade é alterada, o SelectionChangedCommand é executado (com o valor do SelectionChangedCommandParameter sendo repassado para o ICommand) e o evento SelectionChanged é acionado.

O exemplo XAML a seguir mostra uma CollectionView que pode responder à seleção de um único item:

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

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView
{
    SelectionMode = SelectionMode.Single
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
collectionView.SelectionChanged += OnCollectionViewSelectionChanged;

Nesse exemplo de código, o manipulador de eventos OnCollectionViewSelectionChanged é executado quando o evento SelectionChanged é acionado, com o manipulador de eventos recuperando o item selecionado anteriormente e o item selecionado atual:

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string previous = (e.PreviousSelection.FirstOrDefault() as Monkey)?.Name;
    string current = (e.CurrentSelection.FirstOrDefault() as Monkey)?.Name;
    ...
}

Importante

O evento SelectionChanged pode ser acionado por alterações que ocorrem como resultado da alteração da propriedade SelectionMode.

As capturas de tela a seguir mostram a seleção de um único item em um CollectionView:

Captura de tela de uma lista vertical CollectionView com seleção única, no iOS e no Android

Seleção múltipla

Quando a propriedade SelectionMode é definida como Multiple, vários itens podem ser selecionados na CollectionView. Quando os itens forem selecionados, a SelectedItems propriedade será definida como os itens selecionados. Quando essa propriedade é alterada, o SelectionChangedCommand é executado (com o valor do SelectionChangedCommandParameter sendo repassado para o ICommand) e o evento SelectionChanged é acionado.

O exemplo XAML a seguir mostra uma CollectionView que pode responder à seleção de vários itens:

<CollectionView ItemsSource="{Binding Monkeys}"
                SelectionMode="Multiple"
                SelectionChanged="OnCollectionViewSelectionChanged">
    ...
</CollectionView>

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView
{
    SelectionMode = SelectionMode.Multiple
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
collectionView.SelectionChanged += OnCollectionViewSelectionChanged;

Nesse exemplo de código, o manipulador de eventos OnCollectionViewSelectionChanged é executado quando o evento SelectionChanged é acionado, com o manipulador de eventos recuperando os itens selecionados anteriormente e os itens selecionados atuais:

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var previous = e.PreviousSelection;
    var current = e.CurrentSelection;
    ...
}

Importante

O evento SelectionChanged pode ser acionado por alterações que ocorrem como resultado da alteração da propriedade SelectionMode.

As capturas de tela a seguir mostram a seleção de vários itens em um CollectionView:

Captura de tela de uma lista vertical CollectionView com seleção múltipla, no iOS e Android

Pré-seleção única

Quando a SelectionMode propriedade é definida como Single, um único item no CollectionView pode ser pré-selecionado definindo a SelectedItem propriedade como o item. O exemplo XAML a seguir mostra um CollectionView que pré-seleciona um único item:

<CollectionView ItemsSource="{Binding Monkeys}"
                SelectionMode="Single"
                SelectedItem="{Binding SelectedMonkey}">
    ...
</CollectionView>

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView
{
    SelectionMode = SelectionMode.Single
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
collectionView.SetBinding(SelectableItemsView.SelectedItemProperty, "SelectedMonkey");

Observação

A propriedade SelectedItem tem um modo de vinculação padrão de TwoWay.

Os dados da propriedade SelectedItem se vinculam à propriedade SelectedMonkey do modelo de exibição conectado, que é do tipo Monkey. Por padrão, uma TwoWay associação é usada para que, se o usuário alterar o item selecionado, o valor da SelectedMonkey propriedade seja definido como o objeto selecionado Monkey . A propriedade SelectedMonkey é definida na classe MonkeysViewModel e configurada para o quarto item da coleção Monkeys:

public class MonkeysViewModel : INotifyPropertyChanged
{
    ...
    public ObservableCollection<Monkey> Monkeys { get; private set; }

    Monkey selectedMonkey;
    public Monkey SelectedMonkey
    {
        get
        {
            return selectedMonkey;
        }
        set
        {
            if (selectedMonkey != value)
            {
                selectedMonkey = value;
            }
        }
    }

    public MonkeysViewModel()
    {
        ...
        selectedMonkey = Monkeys.Skip(3).FirstOrDefault();
    }
    ...
}

Portanto, quando o CollectionView aparece, o quarto item da lista é pré-selecionado:

Captura de tela de uma lista vertical CollectionView com pré-seleção única, no iOS e no Android

Pré-seleção múltipla

Quando a SelectionMode propriedade é definida como Multiple, vários itens no CollectionView podem ser pré-selecionados. O exemplo XAML a seguir mostra um CollectionView que habilitará a pré-seleção de vários itens:

<CollectionView x:Name="collectionView"
                ItemsSource="{Binding Monkeys}"
                SelectionMode="Multiple"
                SelectedItems="{Binding SelectedMonkeys}">
    ...
</CollectionView>

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView
{
    SelectionMode = SelectionMode.Multiple
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
collectionView.SetBinding(SelectableItemsView.SelectedItemsProperty, "SelectedMonkeys");

Observação

A propriedade SelectedItems tem um modo de vinculação padrão de OneWay.

Os dados da propriedade SelectedItems se vinculam à propriedade SelectedMonkeys do modelo de exibição conectado, que é do tipo ObservableCollection<object>. A propriedade SelectedMonkeys é definida na classe MonkeysViewModel e configurada para o segundo, quarto e quinto itens da coleção Monkeys:

namespace CollectionViewDemos.ViewModels
{
    public class MonkeysViewModel : INotifyPropertyChanged
    {
        ...
        ObservableCollection<object> selectedMonkeys;
        public ObservableCollection<object> SelectedMonkeys
        {
            get
            {
                return selectedMonkeys;
            }
            set
            {
                if (selectedMonkeys != value)
                {
                    selectedMonkeys = value;
                }
            }
        }

        public MonkeysViewModel()
        {
            ...
            SelectedMonkeys = new ObservableCollection<object>()
            {
                Monkeys[1], Monkeys[3], Monkeys[4]
            };
        }
        ...
    }
}

Portanto, quando o CollectionView aparece, o segundo, quarto e quinto itens da lista são pré-selecionados:

Captura de tela de uma lista vertical CollectionView com pré-seleção múltipla, no iOS e no Android

Limpar seleções

As propriedades SelectedItem e SelectedItems podem ser removidas ao defini-las ou aos objetos aos quais se vinculam como null.

Alterar a cor do item selecionado

A CollectionView tem um VisualState Selected que pode ser usado para iniciar uma alteração visual para o item selecionado na CollectionView. Um caso de uso comum para esse VisualState é alterar a cor da tela de fundo do item selecionado, que é mostrada no seguinte exemplo XAML:

<ContentPage ...>
    <ContentPage.Resources>
        <Style TargetType="Grid">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal" />
                        <VisualState x:Name="Selected">
                            <VisualState.Setters>
                                <Setter Property="BackgroundColor"
                                        Value="LightSkyBlue" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
    </ContentPage.Resources>
    <StackLayout Margin="20">
        <CollectionView ItemsSource="{Binding Monkeys}"
                        SelectionMode="Single">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10">
                        ...
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>
</ContentPage>

Importante

O Style que contém o VisualState Selected precisa ter um valor da propriedade TargetType que seja o tipo do elemento raiz do DataTemplate, que é definido como o valor da propriedade ItemTemplate.

Nesse exemplo, o valor da propriedade Style.TargetType é definido como Grid porque o elemento raiz do ItemTemplate é uma Grid. O Selected VisualState especifica que, quando um item no CollectionView é selecionado, o BackgroundColor do item será definido como LightSkyBlue:

Captura de tela de uma lista vertical CollectionView com uma única cor de seleção personalizada, no iOS e no Android

Para obter mais informações sobre estados visuais, consulte Xamarin.Forms Gerenciador de Estado Visual.

Desabilitar a seleção

A seleção da CollectionView é desabilitada por padrão. No entanto, se uma CollectionView tiver uma seleção habilitada, esta poderá ser desabilitada ao definir a propriedade SelectionMode como None:

<CollectionView ...
                SelectionMode="None" />

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView
{
    ...
    SelectionMode = SelectionMode.None
};

Quando a propriedade SelectionMode é definida como None, os itens em CollectionView não podem ser selecionados, a propriedade SelectedItem permanecerá null e o evento SelectionChanged não será acionado.

Observação

Quando um item tiver sido selecionado e a propriedade SelectionMode for alterada de Single para None, a propriedade SelectedItem será definida como null e o evento SelectionChanged será acionado com uma propriedade CurrentSelection vazia.