c# - ejemplo - xamarin bindingcontext
Administrar selecciones múltiples con MVVM (4)
Agregue una propiedad IsSelected
a su hijo ViewModel ( OrderViewModel
en su caso):
public bool IsSelected { get; set; }
Enlace la propiedad seleccionada en el contenedor a esto (para ListBox en este caso):
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
IsSelected
se actualiza para que coincida con el campo correspondiente en el contenedor.
Puede obtener los elementos secundarios seleccionados en el modelo de vista haciendo lo siguiente:
public IEnumerable<OrderViewModel> SelectedOrders
{
get { return Orders.Where(o => o.IsSelected); }
}
En mi viaje hacia el aprendizaje de MVVM, he establecido una comprensión básica de WPF y el patrón ViewModel. Estoy utilizando la siguiente abstracción al proporcionar una lista y estoy interesado en un solo elemento seleccionado.
public ObservableCollection<OrderViewModel> Orders { get; private set; }
public ICollectionView OrdersView
{
get
{
if( _ordersView == null )
_ordersView = CollectionViewSource.GetDefaultView( Orders );
return _ordersView;
}
}
private ICollectionView _ordersView;
public OrderViewModel CurrentOrder
{
get { return OrdersView.CurrentItem as OrderViewModel; }
set { OrdersView.MoveCurrentTo( value ); }
}
A continuación, puedo vincular el OrdersView junto con la ordenación y filtrado de apoyo a una lista en WPF:
<ListView ItemsSource="{Binding Path=OrdersView}"
IsSynchronizedWithCurrentItem="True">
Esto funciona muy bien para vistas de selección única. Pero también me gustaría admitir selecciones múltiples en la vista y hacer que el modelo se vincule a la lista de elementos seleccionados.
¿Cómo vincularía ListView.SelectedItems a una propiedad de respaldo en ViewModel?
Puedo asegurarle que SelectedItems
es enlazable como un CommandParameter
XAML
Hay una solución simple para este problema común; para que funcione, debes seguir TODAS las siguientes reglas:
Siguiendo la sugerencia de Ed Ball , en su enlace de datos del comando XAML, defina el atributo
CommandParameter
ANTES del atributoCommand
. Este es un error que consume mucho tiempo .Asegúrese de que los métodos
CanExecute
yExecute
suICommand
tengan un parámetro de tipoobject
. De esta forma, puede evitar las excepciones deCommandParameter
silenciadas que se producen cada vez que el tipoCommandParameter
laCommandParameter
de datos no coincide con el tipo de parámetro de su método deCommand
:private bool OnDeleteSelectedItemsCanExecute(object SelectedItems) { // Your code goes here } private bool OnDeleteSelectedItemsExecute(object SelectedItems) { // Your code goes here }
Por ejemplo, puede enviar una propiedad SelectedItems
ListView
/ ListBox
a sus métodos ICommand
o al ListView
/ ListBox
. Genial, ¿verdad?
Espero que esto evite que alguien pase la gran cantidad de tiempo que hice para descubrir cómo recibir SelectedItems
como un parámetro CanExecute
.
Si está usando MVVM-LIGHT puede usar este patrón:
No es especialmente elegante, pero parece que debería ser confiable al menos
Uno puede intentar crear una propiedad adjunta.
Si lo hace, le ahorrará a uno agregar la propiedad IsSelected
para todas y cada una de las listas que enlaza. Lo hice para ListBox
, pero puede modificarse para usarlo en una vista de lista.
<ListBox SelectionMode="Multiple"
local:ListBoxMultipleSelection.SelectedItems="{Binding SelectedItems}" >
Más información: WPF - Vinculando ListBox SelectedItems - Propiedad adjunta VS Style .