MvvMCross bind command with parameter (in C# code)

14,122

Solution 1

Android and iOS buttons don't have CommandParameter properties in the same way that Windows ones do.

However, MvvmCross did recently introduce a way to introduce CommandParameter bindings via Value Converters - see http://slodge.blogspot.co.uk/2013/06/commandparameter-binding.html

This binding should work as:

 bindingset
    .Bind(saveButton)
    .To(vm => vm.SaveDealerDataCommand)
    .WithConversion("CommandParameter", true);     

or:

 bindingset
    .Bind(saveButton)
    .To(vm => vm.SaveDealerDataCommand)
    .WithConversion(new MvxCommandParameterValueConverter(), true);     

Note that this CommandParameter binding isn't completely in the 3.0.8.1 package which is the stable nuget release, so to make this work you may need to either:

  1. Add this manual value converter registration in your Setup.cs

    protected override void FillValueConverters(IMvxValueConverterRegistry registry)
    {
        base.FillValueConverters(registry);
        registry.AddOrOverwrite(
            "CommandParameter", 
            new Cirrious.MvvmCross.Binding.MvxCommandParameterValueConverter()
        );
    }
    
  2. Or use one of the beta nuget packages uploaded since 3.0.8.1 (set nuget to include prereleases to see these packages).

  3. Or build the source yourself

Solution 2

To achieve your dynamic command parameter using the text in one of your UITextField controls, you could bind the text in that UITextField to a string property on you ViewModel and the code that runs in your button's bound command would be able to access the value via that property when it executes.

In your ViewController, something like:

UITextField textField = new UTextField();
textField.Frame = new RectangleF(0,0,120,30);
Add(textField);
UIButton button = new UIButton();
button.Frame = new RectangleF(70,40,50,30);
button.SetTitle("Click Me");
Add(button);

var bindingSet = this.CreateBindingSet<MyView, MyViewModel>();
bindingSet.Bind(textField).To(vm => vm.StringProperty);
bindingSet.Bind(button).To(vm => vm.ClickCommand);
bindingSet.Apply();

Then, in your ViewModel:

private string _stringProperty = string.Empty;
public string StringProperty
{
    get { return _stringProperty; }
    set
    {
        _stringProperty = value;
        RaisePropertyChanged(() => StringProperty);
    }
}
public ICommand ClickCommand
{
    get
    {
        return new MvxCommand(HandleClick);
    }
}

public void HandleClick()
{
    //Code that accesses StringProperty (which contains the UITextField's value)
}
Share:
14,122
Sven-Michael Stübe
Author by

Sven-Michael Stübe

M.Sc. in Computer Science. I'm a software engineer and mainly interested in C#/.NET and Xamarin mobile XPlatform development. :D

Updated on June 15, 2022

Comments

  • Sven-Michael Stübe
    Sven-Michael Stübe about 1 year

    How can I bind a command to a button in code in MvvMCross (Xamarin.iOS) with specifying a command parameter?

    // command definition
    public MvxCommand SaveDealerDataCommand
    {
        get { return new MvxCommand<bool>(DoSaveDealerDataAction); }
    }
    
    public void DoSaveDealerDataAction(bool show)
    {
        //...
    }
    
    // binding
    bindingset.Bind(saveButton).To(vm => vm.SaveDealerDataCommand); 
    

    Where can I specify the parameter (true/false) that will be passed to the command?

  • Michael
    Michael over 9 years
    Is there any new update to this answer? I'd like to have a dynamic command parameter in iOS for my UIButton. For example, when you click the button, it would call my command with the current Text in one of my UITextField controls...and all hooked up with .Bind.
  • Sven-Michael Stübe
    Sven-Michael Stübe about 9 years
    Hi, sorry, but that doesn't fit my problem (from 1 year ago). The question targeted command parameters.
  • jyarnott
    jyarnott about 9 years
    Sorry, I was attempting to answer the question posed by Michael in the Comment below your orginal post.