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:
-
Following Ed Ball's suggestion, on your XAML command databinding, define the
CommandParameter
attribute BEFORE theCommand
attribute. This a very time-consuming bug. -
Make sure your
ICommand
'sCanExecute
andExecute
methods have a parameter of typeobject
. This way you can prevent silenced cast exceptions that occur whenever the databinding'sCommandParameter
type does not match yourCommand
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