2012-10-18 9 views
7

Mam przyciskJak korzystać CanExecute z Mvvmcross

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

I mam Polecenie to

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

Następnie chcę, aby włączyć/wyłączyć DisconnectCommand użyciu

DisconnectCommand.CanExecute(this.GetService<IConnectionService>().UsbConnected); 

Ale to wyraźnie nie tak (nie działa), wprowadziłem check jako parametr, ale zwykle zrobiłbym

DisconnectCommand.CanExecute = someBool; 

Ale nie ma właściwości do ustawienia, więc jak sobie z tym poradzić?

+0

Czy 'UsbConnected' jest metodą lub właściwością? –

+0

Jest to własność – Mech0z

Odpowiedz

7

Aby dowiedzieć się, jak używać CanExecute, spójrz na Silverlight lub WPF - istnieje wiele blogów, które mówią o tym, jak używać ICommand - np. http://weblogs.asp.net/nmarun/archive/2009/12/02/using-icommand-silverlight-4.aspx lub http://blog.galasoft.ch/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx

Przykładem może być coś takiego:

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 */; 
} 

Jest jeden mały problem chociaż ....

CanExecute tak naprawdę nie jest w pełni wdrożony we wszystkich MvxBindings całej wszystkie platformy ... Dla niektórych z nich zadziała, ale dla niektórych z nich nie będzie - i tak naprawdę nie wiem, które są obecnie! Jeśli natkniesz się na kwestii, to proszę dać mi znać (przez problemy GitHub) i będą one dostać stałe ...


osobiście ... Nie mają tendencję do używania CanExecute - staram zamiast użyć oddziel własność Boolean, którą następnie wiążę z jakąkolwiek właściwością dostępną na kontrole - np Większość kontrole mają coś podobnego Enabled, IsEnabled, Disabled, IsDisabled itd

ja generalnie łatwiej (i bardziej czytelny) ustawić właściwość logiczna zamiast zadzwonić RaiseCanExecuteChanged

np Chciałbym użyć coś takiego:

<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'}}" /> 

Można zdecydowanie twierdzą, że podejście CanExecute ma swoje zalety - ponieważ utrzymuje logikę polecenia w jednym obiekcie, i dlatego może być stosowany w celu zapobiegania Execute połączeń zachodzących w RelayCommand . Dlatego cieszę się, że próbuję naprawiać błędy CanExecute w powiązaniach mvvmcross, gdy je znajdziemy.

+1

myślę, że jest to zły pomysł, aby nie korzystać z wbudowanych funkcji. Twoje podejście do booleansa dodaje sporo bałaganu do bazy kodu. –

+2

Tak ... ale nie jesteś jedynym, który ma napisać wszystkie powiązania dla MonoDroid i MonoTouch :) – Stuart

+0

Niestety, ja nie rozumiem tego komentarza :-) –

3

Aby odpowiedzieć na odpowiedź Stuarta, łatwo jest obsłużyć zarówno ICommand.CanExecute, jak i prezentujące właściwości, aby obsługiwać połączenia Mvx w systemie Android i iOS.

Aby to zrobić, przekonwertuj typowe metody CanExecute() na właściwości, a następnie dodaj procedury obsługi do CanExecuteChanged, która wywołuje RaisePropertyChanged dla powiązanej właściwości. Następnie użyj normalnie RaiseCanExecuteChanged, a zdarzenie PropertyChanged zostanie również wyrzucone.

... 

    // constructor 
    public SomeClass() 
    { 

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

    public bool CanDoSomething 
    { 
     get { ... } 
    } 

    ...