Managing multiple selections with MVVM

Solution 1:

Add an IsSelected property to your child ViewModel (OrderViewModel in your case):

public bool IsSelected { get; set; }

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

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

IsSelected is updated to match the corresponding field on the container.

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

Solution 2:

I can assure you: SelectedItems is indeed bindable as a XAML CommandParameter

There is a simple solution to this common issue; to make it work you must follow ALL the following rules:

  1. Following Ed Ball's suggestion, on your XAML command databinding, define the CommandParameter attribute BEFORE the Command attribute. This a very time-consuming bug.

    enter image description here

  2. Make sure your ICommand's CanExecute and Execute methods have a parameter of type object. This way you can prevent silenced cast exceptions that occur whenever the databinding's CommandParameter type does not match your Command method's parameter type:

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

For example, you can either send a ListView/ListBox's SelectedItems property to your ICommand methods or the ListView/ListBox itself. Great, isn't it?

I hope this prevents someone from spending the huge amount of time I did to figure out how to receive SelectedItems as a CanExecute parameter.

Solution 3:

One can try creating an attached property.

Doing so will save one from adding the IsSelected property for each and every list you bind. I have done it for ListBox, but it can be modified for use a in a list view.

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

More info: WPF – Binding ListBox SelectedItems – Attached Property VS Style .

Solution 4:

If you're using MVVM-LIGHT you can use this pattern:

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

Not especially elegant but looks like it should be reliable at least