Compartir a través de


Configurar selección de elementos de CollectionView

Examinar ejemplo. Examinar el ejemplo

La interfaz de usuario de la aplicación multiplataforma de .NET (.NET MAUI) 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 color del elemento seleccionado en: 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 la captura de pantalla siguiente se muestra la selección de un solo elemento en una CollectionView:

Recorte de pantalla de una lista vertical CollectionView con selección única.

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 establece en los elementos seleccionados. Cuando cambia esta propiedad, el SelectionChangedCommand se ejecuta (con el valor de SelectionChangedCommandParameter que pasa a ICommand) y se desencadena el evento SelectionChanged.

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 la captura de pantalla siguiente se muestra la selección de varios elementos en una CollectionView:

Recorte de pantalla de una lista vertical CollectionView con varias selecciones.

Preselección única

Cuando la propiedad SelectionMode se establece en Single, se puede preseleccionar un solo elemento en la CollectionView estableciendo la propiedad SelectedItemen el elemento. En el ejemplo XAML siguiente se muestra una CollectionView que preselecciona un solo 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 TwoWay para que, si el usuario cambia el elemento seleccionado, el valor de la propiedad SelectedMonkey se establezca en el objeto seleccionado Monkey. 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 CollectionView aparece, el cuarto elemento de la lista se preselecciona:

Recorte de pantalla de una lista vertical CollectionView con una sola preselección.

Preselección múltiple

Cuando la SelectionMode propiedad se establece Multipleen , se pueden preseleccionar varios elementos de .CollectionView En el ejemplo XAML siguiente se muestra una CollectionView que habilita 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 CollectionView aparece, se preseleccionan el segundo, cuarto y quinto elemento de la lista:

Recorte de pantalla de una lista vertical CollectionView con varias preselecciones.

Borrar selecciones

Las propiedades SelectedItem y SelectedItems se pueden borrar estableciéndolos o los objetos a los que se enlazan en null. Cuando se borra cualquiera de estas propiedades, el evento SelectionChanged se genera con una propiedad vacía CurrentSelection y el SelectionChangedCommand se ejecuta .

Control de la reselección

Un escenario común es que los usuarios seleccionen un elemento en CollectionView y, luego, vayan a otra página. Cuando regresan, el elemento sigue seleccionado, por lo que no podrán volver a seleccionarlo. Para habilitar la reselección, debes borrar la selección de elementos en CollectionView:

<CollectionView ...
                SelectionChanged="OnCollectionViewSelectionChanged" />

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

CollectionView collectionView = new CollectionView();
collectionView.SelectionChanged += OnCollectionViewSelectionChanged;

El siguiente ejemplo muestra el código de controlador de eventos correspondiente al evento SelectionChanged:

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var cv = (CollectionView)sender;
    if (cv.SelectedItem == null)
        return;

    cv.SelectedItem = null;
}

Cambiar el color del elemento seleccionado

CollectionView tiene un objeto SelectedVisualState que se puede usar para iniciar un cambio visual en el elemento seleccionado en 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>
    <Grid Margin="20">
        <CollectionView ItemsSource="{Binding Monkeys}"
                        SelectionMode="Single">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10">
                        ...
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>
</ContentPage>

Importante

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

El código de C# equivalente para el estilo que contiene el estado visual es:

using static Microsoft.Maui.Controls.VisualStateManager;
...

Setter backgroundColorSetter = new() { Property = BackgroundColorProperty, Value = Colors.LightSkyBlue };
VisualState stateSelected = new() { Name = CommonStates.Selected, Setters = { backgroundColorSetter } };
VisualState stateNormal = new() { Name = CommonStates.Normal };
VisualStateGroup visualStateGroup = new() { Name = nameof(CommonStates), States = { stateSelected, stateNormal } };
VisualStateGroupList visualStateGroupList = new() { visualStateGroup };
Setter vsgSetter = new() { Property = VisualStateGroupsProperty, Value = visualStateGroupList };
Style style = new(typeof(Grid)) { Setters = { vsgSetter } };

// Add the style to the resource dictionary
Resources.Add(style);

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 Selected VisualState especifica que cuando se selecciona un elemento de CollectionView, el BackgroundColor del elemento se establece en LightSkyBlue:

Recorte de pantalla de una lista vertical CollectionView con un único color de selección personalizado.

Para obtener más información sobre los estados visuales, consulta Estados visuales.

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 la CollectionView no se pueden seleccionar, la propiedad SelectedItem permanece null y el evento SelectionChanged no se desencadena.

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.