带参数的MvvMCross bind命令(在C#代码中)

时间:2013-07-05 15:51:36

标签: binding parameters xamarin.ios command mvvmcross

如何通过指定命令参数将命令绑定到MvvMCross(Xamarin.iOS)代码中的按钮?

// command definition
public MvxCommand SaveDealerDataCommand
{
    get { return new MvxCommand<bool>(DoSaveDealerDataAction); }
}

public void DoSaveDealerDataAction(bool show)
{
    //...
}

// binding
bindingset.Bind(saveButton).To(vm => vm.SaveDealerDataCommand); 

在哪里可以指定将传递给命令的参数(true / false)?

3 个答案:

答案 0 :(得分:9)

Android和iOS按钮没有CommandParameter属性,就像Windows一样。

然而,MvvmCross最近推出了一种通过值转换器引入CommandParameter绑定的方法 - 请参阅http://slodge.blogspot.co.uk/2013/06/commandparameter-binding.html

此绑定应该如下:

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

或:

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

请注意,这个CommandParameter绑定并不完全在3.0.8.1包中,这是稳定的nuget版本,因此为了完成这项工作,您可能需要:

  1. 在Setup.cs中添加此手动值转换器注册

    protected override void FillValueConverters(IMvxValueConverterRegistry registry)
    {
        base.FillValueConverters(registry);
        registry.AddOrOverwrite(
            "CommandParameter", 
            new Cirrious.MvvmCross.Binding.MvxCommandParameterValueConverter()
        );
    }
    
  2. 使用自3.0.8.1以来上传的其中一个beta nuget软件包(设置nuget以包含预发布以查看这些软件包)。

  3. 自行构建源

答案 1 :(得分:1)

要使用其中一个UITextField控件中的文本来实现动态命令参数,可以将该UITextField中的文本绑定到ViewModel上的字符串属性,并且在按钮的绑定命令中运行的代码将是能够在执行时通过该属性访问该值。

在ViewController中,类似于:

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();

然后,在您的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)
}

答案 2 :(得分:0)

要将动态命令参数传递给视图模型中的命令,您可以创建一个新类,例如像这样DynamicCommandParameterValueConverter

    /// <summary>
    /// This class is inspired by MvvmCross MvxCommandParameterValueConverter,
    /// but because we need dynamic command parameters, we need to implement our own combined with a CustomMvxWrappingCommand.
    /// </summary>
    /// <typeparam name="T">The type of the 'selected item' for the command</typeparam>
    /// <typeparam name="TResult">The returned result that is used as input for the command.</typeparam>
    public class DynamicCommandParameterValueConverter<T, TResult> : MvxValueConverter<ICommand, ICommand>
    {
        private readonly Func<T, TResult> commandParameterExpression;

        public DynamicCommandParameterValueConverter(Func<T, TResult> commandParameterExpression)
        {
            this.commandParameterExpression = commandParameterExpression;
        }

        protected override ICommand Convert(ICommand value, Type targetType, object parameter, CultureInfo culture)
        {
            return new CustomMvxWrappingCommand<T, TResult>(value, commandParameterExpression);
        }
    }

CustomMvxWrappingCommandFunc为参数,稍后调用并传递给命令CanExecute/Execute方法。以下是该类的部分内容的片段:

 public void Execute(object parameter)
        {
            if (wrapped == null)
            {
                return;
            }

            if (parameter != null)
            {
                Mvx.Warning("Non-null parameter overridden in MvxWrappingCommand");
            }

            wrapped.Execute(commandParameterOverride((T)parameter));
        }

您可以修改Mvx中的MvxWrappingCommand类来实现上述示例。

全部使用:

            set.Bind(myControl).For(control => control.ItemClick).To(vm => vm.MyCommand).WithConversion(
            new DynamicCommandParameterValueConverter<MyModel, string>((MyModel item) =>
            {
              // Do custom logic before parsing the item..
            }));