mvvmwindows-runtimemvvmcrossportable-class-library

MVVMCross Behaviours and InvokeCommandAction


I'm relatively new to MVVMCross and MVVM architecture.

I'm trying to keep my CodeBehind as clean as possible so I've been using Interactivity:Interaction.Behaviors to trigger a command when clicking on an Item:

<views:MvxStorePage.Resources>
        <core:Theme x:Key="Theme"/>
        <b:NameScopeBinding  x:Key="ModuleGridView" Source="{Binding ElementName=ModuleGridView}" />
</views:MvxStorePage.Resources>
...
<GridView x:Name="ModuleGridView" >
...
<Interactivity:Interaction.Behaviors>
     <Core:EventTriggerBehavior EventName="SelectionChanged">
          <Core:InvokeCommandAction Command="{Binding SelectModuleCommand}" CommandParameter="{Binding Source.SelectedItem, Source={StaticResource ModuleGridView}}" />
     </Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
...
</GridView>

And in my ViewModel:

MvxCommand<object> _selectModuleCommand;
        public ICommand SelectModuleCommand
        {
            get
            {
                _selectModuleCommand = _selectModuleCommand ?? new MvxCommand<object>((obj) => SelectModule(obj));
                return _selectModuleCommand;
            }
        }

        private void SelectModule(object module)
        {
            var test = 1;
        }

Problem is that the object passed in to SelectModule is of type ItemClickedEventArgs which isn't available in the PCL core project where my ViewModels are located. So i can't access the ItemClicked property of that object.

I've tried using this from my ´InvokeCommandAction´

 <Core:InvokeCommandAction Command="{Binding SelectModuleCommand}" CommandParameter="{Binding Source.SelectedItem.ClickedItem, Source={StaticResource ModuleGridView}}" />

But it has no effect, i still get ItemClickedEventArgs as parameter to my Command


Solution

  • Solved using the property InputConverter of InvokeCommandAction.

    <Page.Resource>
        <local:ItemClickedConverter x:Key="ItemClickedConverter" />
    </Page.Resource>
    
    <interactivity:Interaction.Behaviors>
        <icore:EventTriggerBehavior EventName="ItemClick">
            <icore:InvokeCommandAction Command="{Binding SelectModuleCommand}"
                                       InputConverter="{StaticResource ItemClickedConverter}" />
        </icore:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
    

    And here is the implementation for ItemClickedConverter:

    public class ItemClickedConverter : IValueConverter
    {
        public object? Convert(object value, Type targetType, object parameter, string language)
        {
            return value switch {
                null => null,
                ItemClickEventArgs args => args.ClickedItem,
                _ => throw new ArgumentException(),
            };
        }
    
        public object ConvertBack(object value, Type targetType, object parameter,
            string language)
        {
            throw new NotImplementedException();
        }
    }