Search code examples
c#mvvmmauimaui-community-toolkit

Passing multiple parameters from View to a RelayCommand inside a ViewModel, .net MAUI


Can you help me with correct implementation of mvvm commands via RelayCommand? If I pass more than one parameter there (like button and page for animation), an error appears, because there is no proper constructor.

I decided to set the command (RelayCommand) directly on the page (view), and call from there method (that in view model).

[RelayCommand]
public async Task PlayMusic()
{
    await gamePageViewModel.PlayMusic(MusicButton, SoundImg);
}

Can you tell me how to solve this architectural problem?


Solution

  • You could use Maui MultiBinding for CommandParameter.

    Suppose we implement a Button Command which has two parameters, from the Text Property of two labels,

    <Button
        x:Name="CounterBtn"
        Text="Click me"      
        Command="{Binding ClickedCommand}">
        <Button.CommandParameter>
            <MultiBinding Converter="{StaticResource Myconverter}">
                <Binding Path="Text" Source="{x:Reference label1}" />
                <Binding Path="Text" Source="{x:Reference label2}" />
            </MultiBinding>
        </Button.CommandParameter>
    

    We could define our MultiBindingConverter called Myconverter, which implememts IMultiValueConverter. For how to consume the MultiValueConverter, you may refer to Consume a IMultiValueConverter

    public class MyConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            // this values return all command parameters
            return values;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    Then in viewModel, we can get all parameters

        [RelayCommand]
        public async void Clicked(object Parameter)
        {
            var param = Parameter as object[];
            var text1 = param[0];
            var text2 = param[1];