Since none of the other answers helped me (using SelectedItems
as CommandParameter
was always null
), here is a solution for Universal Windows Platform (UWP) apps. It works using Microsoft.Xaml.Interactivity
and Microsoft.Xaml.Interactions.Core
.
Here's the View:
<ListView x:Name="ItemsList">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="SelectionChanged">
<Core:InvokeCommandAction Command="{x:Bind ViewModel.SelectedItemsChanged}" />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<!-- content etc. -->
</ListView>
Here's the ViewModel (RelayCommand
is a class from MVVM Light):
private List<YourType> _selectedItems = new List<YourType>();
private RelayCommand<SelectionChangedEventArgs> _selectedItemsChanged;
public RelayCommand<SelectionChangedEventArgs> SelectedItemsChanged
{
get
{
if (_selectedItemsChanged == null)
_selectedItemsChanged = new RelayCommand<SelectionChangedEventArgs>((selectionChangedArgs) =>
{
// add a guard here to immediatelly return if you are modifying the original collection from code
foreach (var item in selectionChangedArgs.AddedItems)
_selectedItems.Add((YourType)item);
foreach (var item in selectionChangedArgs.RemovedItems)
_selectedItems.Remove((YourType)item);
});
return _selectedItemsChanged;
}
}
Beware that if you are going to remove items from the original collection after the selection is completed (user pushes a button etc.), it will also remove the items from your _selectedItems
list! If you do this in a foreach loop, you'll get an InvalidOperationException
. To avoid this, simply add a guard in the marked place like:
if (_deletingItems)
return;
and then in the method where you for example remove the items, do this:
_deletingItems = true;
foreach (var item in _selectedItems)
YourOriginalCollection.Remove(item);
_deletingItems = false;