如何在Mvvmcross中使用CanExecute

我有一个按钮

我有一个命令

 public IMvxCommand DisconnectCommand { get { return new MvxRelayCommand(this.GetService().Disconnect); } } 

然后我想使用启用/禁用DisconnectCommand

 DisconnectCommand.CanExecute(this.GetService().UsbConnected); 

但这显然是错误的(它不起作用),我把检查作为一个参数,但通常我会这样做

 DisconnectCommand.CanExecute = someBool; 

但是没有设置属性,那么如何解决这个问题呢?

要了解如何使用CanExecute ,请查看Silverlight或WPF – 那里有很多关于如何使用ICommand的博客 – 例如http://weblogs.asp.net/nmarun/archive/2009/12/02 /using-icommand-silverlight-4.aspx或http://blog.galasoft.ch/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx

一个例子是:

 private MvxRelayCommand _disconnectCommand; public IMvxCommand DisconnectCommand { get { if (_disconnectCommand == null) _disconnectCommand = new MvxRelayCommand(this.GetService().Disconnect, item => this.IsItemConnected(item)); return _disconnectCommand; } } private void SomeServiceNotificationHandler() { _disconnectCommand.RaisePropertyChanged(); } private bool IsItemConnected(object thing) { return /* your code */; } 

虽然有一个小问题……

在所有平台上的所有MvxBindings中, CanExecute并没有真正完全实现……它适用于其中一些,但对于其中一些它不会 – 我目前还不知道哪些! 如果您遇到问题,请告诉我(通过GitHub问题),他们将得到修复……


个人…我不倾向于使用CanExecute – 我倾向于使用一个单独的布尔属性,然后我绑定到控件上可用的任何属性 – 例如,大多数控件具有EnabledIsEnabledDisabledIsDisabled等等。

我通常发现设置布尔属性比调用RaiseCanExecuteChanged更容易(也更可读)

例如,我会使用类似的东西:

  

你肯定可以说CanExecute方法有优势 – 因为它将Command逻辑保存在一个对象中,并且因为它可以用来防止在RelayCommand发生Execute调用。 这就是为什么我很乐意尝试修复mvvmcross绑定中的CanExecute错误。

为了跟进Stuart的回答,很容易同时支持ICommand.CanExecute和暴露属性以支持Android和iOS Mvx绑定。

为此,将典型的CanExecute( )方法转换为属性,然后将处理程序添加到在关联属性上调用RaisePropertyChanged 。 然后正常使用RaiseCanExecuteChanged ,同时也会触发PropertyChanged事件。

  ... // constructor public SomeClass() { DoSomethingCommand = new MvxCommand(OnDoSomething, () => CanDoSomething); DoSomethingCommand .CanExecuteChanged += (sender, args) => RaisePropertyChanged(() => CanDoSomething); } public bool CanDoSomething { get { ... } } ...