Administrar selecciones múltiples con MVVM

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 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:

  

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?

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):

    

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 SelectedOrders { get { return Orders.Where(o => o.IsSelected); } } 

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:

  1. Siguiendo la sugerencia de Ed Ball , en su enlace de datos del comando XAML, defina el atributo CommandParameter ANTES del atributo Command . Este es un error que consume mucho tiempo .

    enter image description here

  2. Asegúrese de que los métodos CanExecute y Execute su ICommand tengan un parámetro de tipo object . De esta forma, puede evitar las excepciones de CommandParameter silenciadas que se producen cada vez que el tipo CommandParameter la CommandParameter de datos no coincide con el tipo de parámetro de su método de Command :

     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 .

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.

  

Más información: WPF – Vinculando ListBox SelectedItems – Propiedad adjunta VS Style .

Si está usando MVVM-LIGHT puede usar este patrón:

http://blog.galasoft.ch/archive/2010/05/19/handling-datagrid.selecteditems-in-an-mvvm-friendly-manner.aspx

No es especialmente elegante, pero parece que debería ser confiable al menos