xamllistviewwinui-3multipleselectioncommandparameter

WinUI 3 Selected Items from ListView send with CommandParameter


I have a WinUI 3 project scaffolded with Template Studio. A ListView with Multiple selection mode. I use MVVM, so binding through commands to the view model. When I change selections inside my list, the program enters my method which is good. But my parameter is null.

How can I when I change selections inside my list to send the elements to a method inside my view model. CommandParameter="{Binding}" might be the problem.

MyPage.xaml

<ListView
    SelectionMode="Multiple"
    ItemsSource="{x:Bind ViewModel.ValidationFlagsList, Mode=OneTime}"
    SelectedValuePath="Key"
    DisplayMemberPath="Value">
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="SelectionChanged">
            <core:InvokeCommandAction Command="{x:Bind ViewModel.FlagCheckBoxChangedCommand}" CommandParameter="{Binding}" /> 
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</ListView>

MyViewModel.cs

public IEnumerable<KeyValuePair<string, string>> ValidationFlagsList => EnumExtensions.GetAllValuesAndDescriptions<ValidationFlag>();

public ICommand FlagCheckBoxChangedCommand { get; }

ctor() 
{
    FlagCheckBoxChangedCommand = new RelayCommand<object>(FlagCheckBox_Changed);
}


private void FlagCheckBox_Changed(object validationFlag)
{
    // Problem: method is called, but parameter is null
}

Solution

  • You just need to remove the CommandParameter and the SelectionChangedEventArgs will be passed to the command.

    <ListView
        DisplayMemberPath="Value"
        ItemsSource="{x:Bind ViewModel.ValidationFlagsList, Mode=OneTime}"
        SelectedValuePath="Key"
        SelectionMode="Multiple">
        <interactivity:Interaction.Behaviors>
            <core:EventTriggerBehavior EventName="SelectionChanged">
                <core:InvokeCommandAction Command="{x:Bind ViewModel.FlagCheckBoxChangedCommand}" />
            </core:EventTriggerBehavior>
        </interactivity:Interaction.Behaviors>
    </ListView>
    

    Then in SelectionChangedEventArgs, you'll get AddedItems and RemovedItems.

    BTW, the ListView has a SelectedItems property but it's just a plain property and not a DependencyProperty, so unfortunately you can't use it in bindings. Here's a workaround if you are interested.