Question

Au cours de mon apprentissage de MVVM, j'ai acquis une compréhension de base de WPF et du modèle ViewModel. J'utilise l'abstraction suivante pour fournir une liste et je suis intéressé par un seul élément sélectionné.

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

Je peux ensuite lier OrdersView avec la prise en charge du tri et du filtrage à une liste dans WPF:

<ListView ItemsSource="{Binding Path=OrdersView}" 
          IsSynchronizedWithCurrentItem="True">

Cela fonctionne très bien pour les vues à sélection unique. Mais je voudrais é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 lier ListView.SelectedItems à une propriété de support sur le ViewModel?

Était-ce utile?

La solution

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

public bool IsSelected { get; set; }

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

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
    </Style>
</ListBox.ItemContainerStyle>

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

Vous pouvez obtenir les enfants sélectionnés dans le modèle d'affichage en procédant comme suit:

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

Autres conseils

Je peux vous assurer que SelectedItems peut effectivement être lié en tant que XAML CommandParameter

Il existe une solution simple à ce problème courant. pour que cela fonctionne, vous devez suivre TOUS les règles suivantes:

  1. Après la suggestion d'Ed Ball , définissez le CommandParameter attribut AVANT l'attribut Commande . C’est un bug qui prend beaucoup de temps .

    entrer la description de l

  2. Assurez-vous que vos méthodes CanExecute et Execute de ICommand ont un paramètre de type objet . . Ainsi, vous pouvez empêcher les exceptions silencieuses de se produire lorsque le type CommandParameter de la liaison de données ne correspond pas au type de paramètre de votre méthode 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 de ListView / à ListBox à vos méthodes ICommand ou ListView / ListBox lui-même. Génial, n'est-ce pas?

J'espère que cela empêchera quelqu'un de passer beaucoup de temps à comprendre comment recevoir SelectedItems en tant que paramètre CanExecute .

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

Cela vous évitera d’ajouter la propriété IsSelected à chaque liste que vous liez. Je l’ai fait pour ListBox , mais il peut être modifié pour être utilisé dans une vue en liste.

<ListBox SelectionMode="Multiple"
         local:ListBoxMultipleSelection.SelectedItems="{Binding SelectedItems}" >

Plus d'infos: WPF - Liaison ListBox SelectedItems - Propriété jointe VS Style .

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

https: // galasoft .ch / posts / 2010/05 / processing-datagrid-selecteditems-in-an-mvvm-friendly-way

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top