1

I am trying to pass two ICommand parameters on button click to a method in view model.

Now I am able to pass only one parameter.

Code here.

XAML (View):

<Button x:Name="btnAdd" Command="{Binding AddUserCommand}" 
                        CommandParameter="{Binding IDUser}"/>

View Model:

    public string IDUser
    {
        get
        {
            return this.personalData.UserID;
        }

        set
        {
            if (this.personalData.UserID == value)
            {
                return;
            }

            this.personalData.UserID = value;
            OnPropertyChanged("UserID");
        }
    }


    private RelayCommand addUserCommand;
    public ICommand AddUserCommand
    {
        get
        {
            return addUserCommand ??
                (addUserCommand = new RelayCommand(param => this.AddUser(param.ToString())));
        }
    }

    public vol AddUser(string userId)
    {
         // Do some stuff
    }

Now I want to pass another ICommand parameter on button click. The parameter I want to pass is the value (checked or not) from a checkbox.

<CheckBox x:Name="Status" Content="Married"/>

so that method AddUser in view model will have below signature:

    public vol AddUser(string userId, bool status)
    {
         // Do some stuff
    }

I know it can be done using MultiBinding in combination with a converter but I do not know exactly how to do it. Also I am not understanding at all why a converter is necessary when using multibinding.

7
  • 2
    While the binding is probably more verbose than you would like, it's also probably the right way to go. If you do need a converter, you need it for the same reasons you would return a (DTO) object from a method: because the method can only return one thing. Commented Jul 20, 2017 at 15:42
  • 1
    Maybe a good post to answer why a converter is necessary when using multibinding. Commented Jul 20, 2017 at 15:43
  • 1
    Why isn't the checkbox bound to your view model? If it were, you could simply look at the value. Commented Jul 20, 2017 at 16:50
  • 2
    @user1624552 It is a good idea to bind any value you want to be persistent in WPF. WPF often unloads controls that are not visible, so sometimes you can get weird behaviors for unbound values. For example, if on a TabControl you can change tabs and come back, and all the unbound data is reset because the control was unloaded or reloaded. Or sometimes when minimizing an application and restoring it, it will reset everything because it unloaded and reloaded the control. Commented Jul 20, 2017 at 19:20
  • 1
    I understand the feeling. What you are asking for is possible, sort of, but not without a lot of heavy lifting that really doesn't buy you much. Commented Jul 20, 2017 at 19:38

1 Answer 1

3

A command takes only one parameter. The Execute method of the ICommand interface is defined as:

void Execute(object parameter);

So you can't pass two parameters to a command.

What you could do is to pass an instance of a class that has two properties. This is where the multi converter comes in.

Bind the CommandParameter to two properties and use the converter to return one object.

XAML:

<Button x:Name="btnAdd" Command="{Binding AddUserCommand}">
    <Button.CommandParameter>
        <MultiBinding Converter="{StaticResource yourConverter}">
            <Binding Path="IDUser" />
            <Binding Path="IsChecked" ElementName="Status" />
        </MultiBinding>
    </Button.CommandParameter>
</Button>

Converter:

public class Converter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return new YourClass() { IdUser = values[0] as string, IsChecked = System.Convert.ToBoolean(values[1]) };
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

View Model:

private RelayCommand<YourClass> addUserCommand;
public ICommand AddUserCommand
{
    get
    {
        return addUserCommand ??
            (addUserCommand = new RelayCommand<YourClass>(param => this.AddUser(param)));
    }
}

public vol AddUser(YourClass obj)
{
    string IDUser = obj.IDUser;
    bool isChecked = obj.IsChecked;
    // Do some stuff
}

Of course you must also define the YourClass payload type with the two parameters IDUser and IsChecked.

Sign up to request clarification or add additional context in comments.

1 Comment

@user1624552: Did you try this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.