Manage multiple selections with MVVM

On my MVVM journey, I set up a basic understanding of WPF and the ViewModel template. I use the following abstraction when presenting a list and am interested in one selected item.

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

Then I can associate OrdersView with sorting and filtering support in a list in WPF:

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

This works very well for a single choice. But I would also like to support several options in the view and bind the model to a list of selected elements.

How do I bind ListView.SelectedItems to the backer property in ViewModel?

+55
c # data-binding mvvm
Apr 29 '09 at 16:35
source share
4 answers

Add the IsSelected property IsSelected your child's ViewModel ( OrderViewModel in your case):

 public bool IsSelected { get; set; } 

Bind the selected property to the container to this (for this in the ListBox):

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

IsSelected updated to match the corresponding container field.

You can get the selected children in the view model by doing the following:

 public IEnumerable<OrderViewModel> SelectedOrders { get { return Orders.Where(o => o.IsSelected); } } 
+92
Apr 29 '09 at 16:44
source share
— -

I can assure you: SelectedItems can really be bound as a XAML CommandParameter

There is a simple solution to this common problem; for it to work, you must follow ALL of the following rules:

  • Following the recommendations of Ed Ball , in your binding to the XAML command, specify the CommandParameter attribute BEFORE the Command attribute. This is a very time-consuming error.

    enter image description here

  • Make sure your ICommand CanExecute and Execute methods have a parameter of type object . That way, you can prevent thrown exceptions exceptions that occur whenever the binding type of CommandParameter does not match your parameter type of the Command method:

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

For example, you can send the ListView / ListBox SelectedItems property to your ICommand or ListView / ListBox methods. Great, right?

Hopefully this is stopping someone from spending the huge amount of time I did to figure out how to get SelectedItems as a CanExecute parameter.

+11
Sep 22 '14 at 2:34
source share

You can try to create an attached property.

This will save one of the addition of the IsSelected property for each linked list. I did this for a ListBox , but it can be changed to be used as a list.

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



Additional information: WPF - binding ListBox SelectedItems - binding property VS Style .

+4
May 02 '14 at 18:02
source share

If you are using MVVM-LIGHT, you can use this template:

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

Not particularly elegant, but at least looks

+1
Jul 22 '10 at 23:26
source share



All Articles