如何在Mvvmcross中使用CanExecute

时间:2012-10-18 09:46:13

标签: c# data-binding xamarin.android mvvmcross

我有一个按钮

<Button 
      android:id="@+id/ButtonConnect"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="Disconnect"
      local:MvxBind="{'Click':{'Path':'DisconnectCommand'}}" />

我有一个命令

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

然后我想使用

启用/禁用DisconnectCommand
DisconnectCommand.CanExecute(this.GetService<IConnectionService>().UsbConnected);

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

DisconnectCommand.CanExecute = someBool;

但是没有设置属性,所以如何解决这个问题?

2 个答案:

答案 0 :(得分:7)

要了解如何使用CanExecute,请查看Silverlight或WPF - 那里有很多博客讨论如何使用ICommand - 例如http://weblogs.asp.net/nmarun/archive/2009/12/02/using-icommand-silverlight-4.aspxhttp://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<IConnectionService>().Disconnect, item => this.IsItemConnected(item));
        return _disconnectCommand;
    }
}

private void SomeServiceNotificationHandler()
{
    _disconnectCommand.RaisePropertyChanged();
}

private bool IsItemConnected(object thing)
{
    return /* your code */;
}

虽然有一个小问题......

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


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

我通常发现设置布尔属性比调用RaiseCanExecuteChanged

更容易(也更易读)

e.g。我会使用类似的东西:

<Button 
  android:id="@+id/ButtonConnect"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="Disconnect"
  local:MvxBind="{'Click':{'Path':'DisconnectCommand'},'Enabled':{'Path':'UsbConnected'}}" />

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

答案 1 :(得分:3)

为了跟进Stuart的回答,很容易支持ICommand.CanExecute以及公开属性以支持Android和iOS Mvx绑定。

要执行此操作,请将典型的CanExecute()方法转换为属性,然后将处理程序添加到在关联属性上调用CanExecuteChanged的{​​{1}}。然后正常使用RaisePropertyChanged,同时也会触发RaiseCanExecuteChanged事件。

PropertyChanged