5

如何通过指定命令参数将命令绑定到 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); 

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

4

3 回答 3

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. 或者自己构建源

于 2013-07-05T17:08:12.320 回答
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)
}
于 2014-04-23T13:46:46.310 回答
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);
        }
    }

CustomMvxWrappingCommand接受一个作为参数,然后Func被调用并传递给 commandsCanExecute/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));
        }

您可以修改MvxWrappingCommandMvx 中的类以实现上述示例。

全部使用:

            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..
            }));
于 2015-08-04T13:26:32.707 回答