Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I invoke RelayCommand with multiple parameters?

I need to change some functionality in a WPF app we've written. We use MVVM Light to implement MVVM. Whenever we've needed to pass some parameters to a method we've used MVVM Light's Messenger class. I've got to pass 3 parameters to a method, but I thought I'd try doing this without using the Messenger class, but instead I hoped I could do it using the RelayCommand() method. I did a search and found this post here on SO, from some years ago. But at least to me, I think this won't work as it's using just 1 type; string in this case. After making some trials and realizing that I'd done it wrong, I decided I could probably create a class with the 3 values I need in it as properties of the class, put it into Models folder and use

new RelayCommand<MyClass>()

So, first question, just to verify that I've got the right idea, I think I would do something like this:

new RelayCommand<MyClass>((mc) => MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C)

Is that correct?

Assuming the answer to the above is yes, then how do I actually pass parameters to this when I bind to it in the XAML? This command is going to be associated with a button on the window/page, so I'll be using the Button's Command property. How do I actually pass in the values for the MyClass instances Prop_A, Prop_B and Prop_C?

like image 501
Rod Avatar asked Jun 30 '26 10:06

Rod


2 Answers

So, first question, just to verify that I've got the right idea, I think I would do something like this:

new RelayCommand<MyClass>((mc) => MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C)

This is correct.

Assuming the answer to the above is yes, then how do I actually pass parameters to this when I bind to it in the XAML? This command is going to be associated with a button on the window/page, so I'll be using the Button's Command property. How do I actually pass in the values for the MyClass instances Prop_A, Prop_B and Prop_C?

This will actually depend on where would Prop_A, Prop_B and Prop_C come from. If these properties are already inside your view model, then there is no need for you to pass parameters using XAML.

new RelayCommand<MyClass>((mc) => MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C)

will change to

new RelayCommand<object>((param) => 
{
    // param is not used.
    var mc = this.MC; // assuming your view model holds the mc value
    MyMethod(mc.Prop_A, mc.Prop_B, mc.Prop_C);
});

We must make sure that when we load our view model, we have everything we need. Else, use an IoC to fetch whatever it is you need to.

Binding a parameter to your command is often useful for something like a calculator app where you want to pass the button value to your command such as 0 - 9.

<Button Grid.Row="0" Grid.Column="1" Content="7" Command="{Binding PerformAction}" CommandParameter="7"/>

I would want to stay away from defining classes in your view. For the separation of concern, the view should only know of the properties to be bounded to and not the models.

like image 109
jegtugado Avatar answered Jul 02 '26 00:07

jegtugado


Here is how I did it:

  1. Your CommandRelay object takes object as parameter, you convert that object to object[] then each element to its own object.

    private RelayCommand<object> _YourCommand;
    
    public RelayCommand<object> YourCommand
    {
        get
        {
            return _YourCommand ?? (_YourCommand = new RelayCommand<object>(p =>
            {
                var    values = (object[]) p;
                int    item1  = int.Parse(values[0].ToString());
                string item2  = values[1].ToString();
                double item3  = double.Parse(values[2].ToString());
            }));
        }
    }
    
  2. Then, in xaml (Of course, your Paths in Binding must be valid references to your binded objects)

<Button Command="{Binding YourCommand}">
    	<Button.CommandParameter>
    	    <MultiBinding>
    	        <Binding Path="Item1"/>
    	        <Binding Path="Item2"/>
    	        <Binding Path="Item3"/>
    	    </MultiBinding>
    	</Button.CommandParameter>
</Button>
like image 29
Michael Korin Avatar answered Jul 02 '26 00:07

Michael Korin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!