Xamarin.Forms Selección de CollectionView

Download SampleDescargar el ejemplo

CollectionView define las siguientes propiedades que controlan la selección de elementos:

  • SelectionMode, de tipo SelectionMode, el modo de selección.
  • SelectedItem, de tipo object,el elemento de la lista. Esta propiedad tiene un modo de enlace predeterminado de TwoWay y tiene un valor null cuando no se selecciona ningún elemento.
  • SelectedItems, de tipo IList<object>,los elementos seleccionados de la lista. Esta propiedad tiene un modo de enlace predeterminado de OneWay y tiene un valor null cuando no se selecciona ningún elemento.
  • SelectionChangedCommand, de tipo ICommand, que se ejecuta cuando cambia el elemento seleccionado.
  • SelectionChangedCommandParameter, de tipo object, que es el parámetro que se pasa al objeto SelectionChangedCommand.

Todas estas propiedades están respaldados por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos.

De forma predeterminada, CollectionView la selección está deshabilitada. Pero este comportamiento se puede cambiar estableciendo la propiedad SelectionMode en uno de los miembros de la enumeración SelectionMode:

  • None: indica que no se puede seleccionar ningún elemento. Este es el valor predeterminado.
  • Single : indica que se puede seleccionar un solo elemento, con el elemento seleccionado resaltado.
  • Multiple : indica que se pueden seleccionar varios elementos, con los elementos seleccionados resaltados.

CollectionView define un evento SelectionChanged que se desencadena cuando cambia la propiedad SelectedItem, ya sea debido a que el usuario selecciona un elemento de la lista o cuando una aplicación establece la propiedad. Además, este evento también se desencadena cuando cambia la propiedad SelectedItems. El objeto SelectionChangedEventArgs que acompaña al evento SelectionChanged tiene dos propiedades, ambas de tipo IReadOnlyList<object>.

  • PreviousSelection: la lista de elementos seleccionados antes de cambiar la selección.
  • CurrentSelection: la lista de elementos seleccionados después del cambio de selección.

Además, CollectionView tiene un método UpdateSelectedItems que actualiza la propiedad SelectedItems con una lista de elementos seleccionados, al mismo tiempo que desencadena una única notificación de cambio.

Selección única

Cuando la propiedad SelectionMode se establece en Single, se puede seleccionar un solo elemento en CollectionView. Cuando un elemento está seleccionado, la propiedad SelectedItem se establece en el valor del elemento seleccionado: Cuando esta propiedad cambia, el SelectionChangedCommand se ejecuta (con el valor del SelectionChangedCommandParameter que pasa a ICommand) y el evento SelectionChanged se desencadena.

En el ejemplo XAML siguiente se muestra una CollectionView que puede responder a la selección de elementos únicos:

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

El código de C# equivalente es el siguiente:

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

En este ejemplo de código, el controlador de eventos OnCollectionViewSelectionChanged se ejecuta cuando se desencadena el evento SelectionChanged, con el controlador de eventos recuperando el elemento seleccionado anteriormente y el actual:

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

Importante

El evento SelectionChanged se puede desencadenar mediante cambios que se producen como resultado de cambiar la propiedad SelectionMode.

En las capturas de pantalla siguientes se muestra la selección de un solo elemento en una CollectionView:

Screenshot of a CollectionView vertical list with single selection, on iOS and Android

Selección múltiple

Cuando la propiedad SelectionMode se establece en Multiple, se pueden seleccionar varios elementos de CollectionView. Cuando se seleccionan los elementos, la propiedad SelectedItems se establecerá en los elementos seleccionados. Cuando esta propiedad cambia, el SelectionChangedCommand se ejecuta (con el valor del SelectionChangedCommandParameter que pasa a ICommand) y el evento SelectionChanged se desencadena.

En el ejemplo XAML siguiente se muestra una CollectionView que puede responder a varias selecciones de elementos:

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

El código de C# equivalente es el siguiente:

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

En este ejemplo de código, el controlador de eventos OnCollectionViewSelectionChanged se ejecuta cuando se desencadena el evento SelectionChanged, con el controlador de eventos recuperando los elementos seleccionados anteriormente y los actuales:

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

Importante

El evento SelectionChanged se puede desencadenar mediante cambios que se producen como resultado de cambiar la propiedad SelectionMode.

En las capturas de pantalla siguientes se muestra la selección de varios elementos en una CollectionView:

Screenshot of a CollectionView vertical list with multiple selection, on iOS and Android

Preselección única

Cuando la propiedad SelectionMode se establece en Single, se puede preseleccionar un solo elemento de CollectionView estableciendo la propiedad SelectedItem en el elemento. En el siguiente ejemplo de XAML, se muestra una CollectionView que preselecciona un único elemento:

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

El código de C# equivalente es el siguiente:

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

Nota:

La propiedad SelectedItem tiene un modo de enlace predeterminado de TwoWay.

Los datos de propiedad SelectedItem se enlazan a la propiedad SelectedMonkey del modelo de vista conectado, que es de tipo Monkey. De forma predeterminada, se usa un enlace de TwoWay para que, si el usuario cambia el elemento seleccionado, el valor de la propiedad SelectedMonkey se establezca en el objeto Monkey seleccionado. La propiedad SelectedMonkey se define en la clase MonkeysViewModel y se establece en el cuarto elemento de la colección 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();
    }
    ...
}

Por lo tanto, cuando aparezca CollectionView, el cuarto elemento de la lista estará preseleccionado:

Screenshot of a CollectionView vertical list with single pre-selection, on iOS and Android

Preselección múltiple

Cuando la propiedad SelectionMode se establece en Multiple, se pueden preseleccionar varios elementos de CollectionView. En el ejemplo XAML siguiente se muestra una CollectionView que habilitará la preselección de varios elementos:

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

El código de C# equivalente es el siguiente:

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

Nota:

La propiedad SelectedItems tiene un modo de enlace predeterminado de OneWay.

Los datos de propiedad SelectedItems se enlazan a la propiedad SelectedMonkeys del modelo de vista conectado, que es de tipo ObservableCollection<object>. La propiedad SelectedMonkeys se define en la clase MonkeysViewModel y se establece en los elementos segundo, cuarto y quinto de la colección 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]
            };
        }
        ...
    }
}

Por lo tanto, cuando aparezca CollectionView, los elementos segundo, cuarto y quinto de la lista estarán preseleccionados:

Screenshot of a CollectionView vertical list with multiple pre-selection, on iOS and Android

Borrar selecciones

Las propiedades SelectedItem y SelectedItems se pueden borrar estableciéndolos o los objetos a los que se enlazan en null.

Cambiar el color del elemento seleccionado

CollectionView tiene un SelectedVisualState que se puede usar para iniciar un cambio visual en el elemento seleccionado en la CollectionView. Un caso de uso común para este VisualState es cambiar el color de fondo del elemento seleccionado, que se muestra en el ejemplo XAML siguiente:

<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

El Style que contiene el SelectedVisualState debe tener un valor TargetType de propiedad que sea el tipo del elemento raíz de DataTemplate, que se establece como valor de propiedad ItemTemplate.

En este ejemplo, el valor de la propiedad Style.TargetType se establece en Grid porque el elemento raíz del ItemTemplate es una Grid. El VisualStateSelected especifica que cuando se selecciona un elemento de CollectionView, el BackgroundColor del elemento se establecerá en LightSkyBlue:

Screenshot of a CollectionView vertical list with a custom single selection color, on iOS and Android

Para obtener más información sobre los estados visuales, vea Administrador de estado visual de Xamarin.Forms.

Deshabilitar selección

La selecciónCollectionView está deshabilitada de forma predeterminada. Pero, si una tiene habilitada la selección CollectionView, se puede deshabilitar estableciendo la propiedad SelectionMode en None:

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

El código de C# equivalente es el siguiente:

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

Cuando la propiedad SelectionMode se establece en None, los elementos en CollectionView no se pueden seleccionar, la propiedad SelectedItem permanecerá null y el evento SelectionChanged no se desencadenará.

Nota:

Cuando se ha seleccionado un elemento y la propiedad SelectionMode cambia de Single a None, la propiedad SelectedItem se establecerá en null y el evento SelectionChanged se desencadenará con una propiedad vacía CurrentSelection.