在Xamarin中传递的RelayCommand参数
我是Xamarin cross-platform
新手,虽然我确实有一些WPF
和MVVM
经验,但我仍然使用下面的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
我写了一篇小博客文章 ,其中包含一个完整的工作项目,如果你想看到一个有效的例子。
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