2012-10-18 37 views
7

我有一個按鈕如何使用CanExecute與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; 

但沒有財產設置,所以如何去做這件事?

+0

是'UsbConnected'方法還是屬性? –

+0

這是一個屬性 – Mech0z

回答

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

例如我會使用類似:

<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方法具有優勢 - 因爲它使命令邏輯都在同一個對象,因爲它可以用來防止Execute呼叫RelayCommand內發生。這就是爲什麼我很樂意嘗試修復mvvmcross綁定中的CanExecute錯誤,因爲我們發現它們。

+1

我認爲不使用內置功能是一個壞主意。你用布爾運算符的方法給代碼庫增加了很多混亂。 –

+2

是的......但是你不是那個必須爲MonoDroid和MonoTouch寫出所有綁定的人:) – Stuart

+0

對不起,我不明白那條評論:-) –

3

要跟蹤Stuart的答案,很容易支持ICommand.CanExecute以及公開屬性以支持Android和iOS Mvx綁定。

爲此,請將典型的CanExecute()方法轉換爲屬性,然後將處理程序添加到CanExecuteChanged,該處理程序在關聯的屬性上調用RaisePropertyChanged。然後正常使用RaiseCanExecuteChanged,並且PropertyChanged事件也會被觸發。

... 

    // constructor 
    public SomeClass() 
    { 

     DoSomethingCommand = new MvxCommand(OnDoSomething,() => CanDoSomething); 
     DoSomethingCommand .CanExecuteChanged += (sender, args) => RaisePropertyChanged(() => CanDoSomething); 
    } 

    public bool CanDoSomething 
    { 
     get { ... } 
    } 

    ...