2012-10-18 35 views
7

Tôi có một nútLàm thế nào để sử dụng CanExecute với Mvvmcross

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

Và tôi có một lệnh cho nó

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

Sau đó, tôi muốn bật/tắt DisconnectCommand sử dụng

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

Nhưng thats rõ ràng sai (Nó không hoạt động), tôi đặt kiểm tra như là một tham số aa, nhưng thông thường tôi sẽ làm

DisconnectCommand.CanExecute = someBool; 

Nhưng không có thuộc tính nào để đặt, vậy làm cách nào để thực hiện việc này?

+0

Phương thức hoặc thuộc tính có được 'UsbConnected' không? –

+0

Đây là tài sản – Mech0z

Trả lời

7

Để tìm hiểu cách sử dụng CanExecute, hãy xem Silverlight hoặc WPF - có rất nhiều blog ở đó nói về cách sử dụng ICommand - ví dụ: http://weblogs.asp.net/nmarun/archive/2009/12/02/using-icommand-silverlight-4.aspx hoặc http://blog.galasoft.ch/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx

Một ví dụ sẽ là một cái gì đó như:

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

Có một vấn đề nhỏ mặc dù ....

CanExecute là không thực sự thực hiện đầy đủ trên tất cả các MvxBindings trên tất cả các nền tảng ... Nó sẽ làm việc cho một số người trong số họ, nhưng đối với một số người trong số họ nó sẽ không - và tôi không thực sự biết những người hiện nay! Nếu bạn gặp vấn đề, sau đó xin vui lòng cho tôi biết (thông qua các vấn đề GitHub) và họ sẽ được cố định ...


Cá nhân ... Tôi không có xu hướng sử dụng CanExecute - Tôi có xu hướng thay vì sử dụng một thuộc tính Boolean riêng biệt mà sau đó tôi liên kết với bất kỳ thuộc tính nào có sẵn trên điều khiển - ví dụ hầu hết các điều khiển có cái gì đó như Enabled, IsEnabled, Disabled, IsDisabled vv

tôi thường tìm thấy nó dễ dàng hơn (và dễ đọc hơn) để thiết lập thuộc tính Boolean hơn là để gọi RaiseCanExecuteChanged

ví dụ Tôi muốn sử dụng cái gì đó như:

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

Bạn chắc chắn có thể tranh luận rằng cách tiếp cận CanExecute có lợi thế - bởi vì nó giữ logic lệnh tất cả trong một đối tượng, và vì nó có thể được sử dụng để ngăn chặn các cuộc gọi Execute xảy ra trong RelayCommand . Đó là lý do tại sao tôi rất vui khi cố gắng sửa lỗi CanExecute trong các ràng buộc mvvmcross khi chúng tôi tìm thấy chúng.

+1

Tôi nghĩ rằng không nên sử dụng chức năng được tích hợp sẵn. Cách tiếp cận của bạn với các boolean thêm khá nhiều lộn xộn vào cơ sở mã. –

+2

Có ... nhưng bạn không phải là người phải viết tất cả các ràng buộc cho MonoDroid và MonoTouch :) – Stuart

+0

Xin lỗi, tôi không hiểu rằng bình luận :-) –

3

Để theo dõi câu trả lời của Stuart, thật dễ dàng để hỗ trợ cả hai ICommand.CanExecute cùng với việc hiển thị các thuộc tính để hỗ trợ các ràng buộc Mvx của Android và iOS.

Để thực hiện việc này, chuyển đổi các phương thức điển hình CanExecute() thành thuộc tính, sau đó thêm trình xử lý vào CanExecuteChanged gọi số RaisePropertyChanged trên thuộc tính được liên kết. Sau đó sử dụng RaiseCanExecuteChanged như bình thường và sự kiện PropertyChanged cũng được kích hoạt.

... 

    // constructor 
    public SomeClass() 
    { 

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

    public bool CanDoSomething 
    { 
     get { ... } 
    } 

    ... 
Các vấn đề liên quan