Search code examples
mauimaui-community-toolkit

.net Maui: How to bind SelectedItem in a CollectionView to a command / command parameter in view model in code, not xaml


I have a CollectionView in code, and in fact am using the CommunityToolkit.Maui.Markup extensions to fluently describe the CV.

However, I am unable to find an elegant formulation for binding the SelectedItem to a command parameter in the view model.

The CollectionView has properties:

SelectionChangedCommand
SelectionChagedCommandParameter

My thought was that I could just do something like:

Content = new CollectionView {
    ...
    SelectionChangedCommand = viewModel.SelectionChangedCommand
    ...
}.Bind(CollectionView.SelectionChangedCommandParameterProperty, nameof(CollectionView.SelectedItem));

But this doesn't work - the app crashing immediately on selection with a NullReferenceException in some Xamarin internal code. In fact I can't find any documentation on how to do this using bindings in code (with or without community markup). The only thing i could get working was using events, so something like:

var collectionView = new CollectionView {
...
}

collectionView.SelectionChanged +=
    (sender, e) =>
    {
        if (e.CurrentSelection.FirstOrDefault() is Caption caption)
        {
            viewModel.ItemTappedCommand.Execute(caption);
        }
    };

Content = collectionView;

Can anyone render assistance?


Solution

  • You want to bind the SelectionChangedCommandParameter property to the SelectedItem of the CollectionView. That means the Binding Source for the SelectionChangedCommandParameter property is the CollectionView itself, instead of the items Collection in viewModel.

    So, you could use Relative Binding to achieve this. Try below code in C# Markup,

    new CollectionView {
                ...
                SelectionChangedCommand = ViewModel.SelectionChangedCommand,
                ...
    }.Bind(CollectionView.SelectionChangedCommandParameterProperty, path:nameof(CollectionView.SelectedItem),source:RelativeBindingSource.Self)
    

    Please let me know if you have any questions!