Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MvvMCross bind command with parameter (in C# code)

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?

like image 251
Sven-Michael Stübe Avatar asked Jul 05 '13 15:07

Sven-Michael Stübe


2 Answers

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

like image 118
Stuart Avatar answered Nov 03 '22 20:11

Stuart


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)
}
like image 1
jyarnott Avatar answered Nov 03 '22 18:11

jyarnott