Configurar selección de elementos de CollectionView
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 tipoSelectionMode
, el modo de selección.SelectedItem
, de tipoobject
,el elemento de la lista. Esta propiedad tiene un modo de enlace predeterminado deTwoWay
y tiene un valornull
cuando no se selecciona ningún elemento.SelectedItems
, de tipoIList<object>
,los elementos seleccionados de la lista. Esta propiedad tiene un modo de enlace predeterminado deOneWay
y tiene un valornull
cuando no se selecciona ningún elemento.SelectionChangedCommand
, de tipo ICommand, que se ejecuta cuando cambia el elemento seleccionado.SelectionChangedCommandParameter
, de tipoobject
, que es el parámetro que se pasa al objetoSelectionChangedCommand
.
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:
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:
Preselección única
Cuando la propiedad SelectionMode
se establece en Single
, se puede preseleccionar un solo elemento en la CollectionView estableciendo la propiedad SelectedItem
en 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:
Preselección múltiple
Cuando la SelectionMode
propiedad se establece Multiple
en , 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:
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 Selected
VisualState 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
:
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
.