在Xamarin中传递的RelayCommand参数

我是Xamarin cross-platform新手,虽然我确实有一些WPFMVVM经验,但我仍然使用下面的ICommand实现了解参数化RelayCommand调用的问题。 有人可以解释如何正确地从我的View传递和接收CommandParameter到我绑定的RelayCommand因为这似乎与正常的WPF版本的RelayCommand

  ///  /// A command whose sole purpose is to relay its functionality /// to other objects by invoking delegates. /// The default return value for the CanExecute method is 'true'. ///  needs to be called whenever ///  is expected to return a different value. ///  public class RelayCommand : ICommand { private readonly Action _execute; private readonly Func _canExecute; ///  /// Raised when RaiseCanExecuteChanged is called. ///  public event EventHandler CanExecuteChanged; ///  /// Creates a new command that can always execute. ///  /// The execution logic. public RelayCommand(Action execute) : this(execute, null) { } ///  /// Creates a new command. ///  /// The execution logic. /// The execution status logic. public RelayCommand(Action execute, Func canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } ///  /// Determines whether this  can execute in its current state. ///  ///  /// Data used by the command. If the command does not require data to be passed, this object can be set to null. ///  /// true if this command can be executed; otherwise, false. public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(); } ///  /// Executes the  on the current command target. ///  ///  /// Data used by the command. If the command does not require data to be passed, this object can be set to null. ///  public void Execute(object parameter) { _execute(); } ///  /// Method used to raise the  event /// to indicate that the return value of the  /// method has changed. ///  public void RaiseCanExecuteChanged() { var handler = CanExecuteChanged; if (handler != null) { handler(this, EventArgs.Empty); } } } 

在WPF之前,我曾经有类似的东西:

  

ViewModel端:

  OpenMenuItemCommand = new RelayCommand(OpenMenuItem); ... public void OpenMenuItem(object sender, ItemTappedEventArgs args) { } 

所以我的参数将来自args

我相信你会让事件和命令混乱。 两者之间的一些区别是您需要订阅事件并且必须发生事件。 命令可以被任何人调用,也可以被阻止。

因此,为了让您的示例正常工作,您应该修改代码以允许RelayCommand使用参数执行操作。 此参数将定义参数的类型。 我会使用类似MVVMLight的东西,它包含一个Generic RelayCommand,这样你就不必编写自己的。 完成后,您应该能够将代码更改为这样。

  OpenMenuItemCommand = new RelayCommand(OpenMenuItem); ... public void OpenMenuItem(MenuItem item) { } 

我写了一篇小博客文章 ,其中包含一个完整的工作项目,如果你想看到一个有效的例子。

Xamarin的中继或代理命令

这就是我实现它的方式,我希望它对某些人有所帮助

 public class DelegateCommand : ICommand { ///  /// The _execute ///  private readonly Action _execute; ///  /// The _can execute ///  private readonly Func _canExecute; ///  /// Initializes a new instance of the  class. ///  /// The execute. /// The can execute. /// execute public DelegateCommand(Action execute, Func canExecute) { _execute = execute ?? throw new ArgumentNullException("execute"); if (canExecute != null) { this._canExecute = canExecute; } } ///  /// Initializes a new instance of the DelegateCommand class that /// can always execute. ///  /// The execution logic. /// If the execute argument is null. public DelegateCommand(Action execute) : this(execute, null) { } ///  /// Occurs when changes occur that affect whether the command should execute. ///  public event EventHandler CanExecuteChanged; ///  /// Raises the can execute changed. ///  public void RaiseCanExecuteChanged() { CanExecuteChanged?.Invoke(this, EventArgs.Empty); } ///  /// Defines the method that determines whether the command can execute in its current state. ///  /// Data used by the command. If the command does not require data to be passed, this object can be set to null. /// true if this command can be executed; otherwise, false. public bool CanExecute(object parameter) { return _canExecute == null || _canExecute.Invoke(); } ///  /// Defines the method to be called when the command is invoked. ///  /// Data used by the command. If the command does not require data to be passed, this object can be set to null. public virtual void Execute(object parameter) { if (CanExecute(parameter)) { _execute.Invoke(); } } } ///  /// This class allows delegating the commanding logic to methods passed as parameters, /// and enables a View to bind commands to objects that are not part of the element tree. ///  /// Type of the parameter passed to the delegates public class DelegateCommand : ICommand { ///  /// The execute ///  private readonly Action _execute; ///  /// The can execute ///  private readonly Predicate _canExecute; ///  /// Initializes a new instance of the  class. ///  /// The execute action. /// execute public DelegateCommand(Action execute) : this(execute, null) { } ///  /// Initializes a new instance of the  class. ///  /// The execute. /// The can execute predicate. /// execute public DelegateCommand(Action execute, Predicate canExecute) { _execute = execute ?? throw new ArgumentNullException("execute"); if (canExecute != null) { _canExecute = canExecute; } } ///  /// Occurs when changes occur that affect whether the command should execute. ///  public event EventHandler CanExecuteChanged; ///  /// Raise  event. ///  public void RaiseCanExecuteChanged() { CanExecuteChanged?.Invoke(this, EventArgs.Empty); } ///  /// Determines whether this instance can execute the specified parameter. ///  /// The parameter. /// true if this instance can execute the specified parameter; otherwise, false. public bool CanExecute(object parameter) { return _canExecute == null || _canExecute.Invoke((T)parameter); } ///  /// Executes the specified parameter. ///  /// The parameter. public virtual void Execute(object parameter) { if (CanExecute(parameter)) { _execute((T)parameter); } } } 

在你的视图中

  

在您的视图模型中

 public ICommand LoginCommand { get; } LoginCommand = new DelegateCommand( x => { // x will be containing 12345 // your code });