Gestion de sélections multiples avec MVVM

Lors de mon apprentissage de MVVM, j’ai acquis des connaissances de base sur WPF et le modèle ViewModel. J’utilise l’abstraction suivante pour fournir une liste et je m’intéresse à un seul élément sélectionné.

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 ); } } 

Je peux ensuite associer la OrderView à la prise en charge du sorting et du filtrage dans une liste dans WPF:

  

Cela fonctionne très bien pour les vues à sélection unique. Mais j’aimerais également prendre en charge plusieurs sélections dans la vue et faire en sorte que le modèle soit lié à la liste des éléments sélectionnés.

Comment puis-je lier le ListView.SelectedItems à une propriété de backer sur le ViewModel?

    Ajoutez une propriété IsSelected à votre enfant ViewModel ( OrderViewModel dans votre cas):

     public bool IsSelected { get; set; } 

    Liez la propriété sélectionnée sur le conteneur à ceci (pour ListBox dans ce cas):

        

    IsSelected est mis à jour pour correspondre au champ correspondant du conteneur.

    Vous pouvez obtenir les enfants sélectionnés dans le modèle de vue en procédant comme suit:

     public IEnumerable SelectedOrders { get { return Orders.Where(o => o.IsSelected); } } 

    Je peux vous assurer: SelectedItems est en effet liable en tant que CommandParameter XAML

    Il existe une solution simple à ce problème commun; pour que cela fonctionne, vous devez suivre TOUTES les règles suivantes:

    1. Suite à la suggestion d’Ed Ball , sur la liaison de données de votre commande XAML, définissez l’atsortingbut CommandParameter atsortingbut Command . C’est un bug qui prend beaucoup de temps .

      entrer la description de l'image ici

    2. Assurez-vous que les ICommand CanExecute et Execute votre ICommand ont un paramètre de type object . De cette façon, vous pouvez empêcher les exceptions de CommandParameter silencieuses qui se produisent chaque fois que le type CommandParameter la CommandParameter ne correspond pas au type de paramètre de votre méthode de Command :

       private bool OnDeleteSelectedItemsCanExecute(object SelectedItems) { // Your code goes here } private bool OnDeleteSelectedItemsExecute(object SelectedItems) { // Your code goes here } 

    Par exemple, vous pouvez envoyer une propriété SelectedItems ListView / ListBox à vos méthodes ICommand ou à ListView / ListBox lui-même. Génial, n’est-ce pas?

    J’espère que cela empêche quelqu’un de passer énormément de temps à comprendre comment recevoir SelectedItems tant que paramètre CanExecute .

    On peut essayer de créer une propriété attachée.

    Cela évitera d’append la propriété IsSelected pour chaque liste que vous associez. Je l’ai fait pour ListBox , mais il peut être modifié pour utiliser un dans une vue de liste.

      

    Plus d’infos: WPF – Liaison ListBox SelectedItems – Propriété attachée VS Style .

    Si vous utilisez MVVM-LIGHT, vous pouvez utiliser ce modèle:

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

    Pas particulièrement élégant, mais il devrait au moins être fiable