第十八章:MVVM(七)

Command接口

數據綁定非常強大。數據綁定將View中可視元素的屬性與ViewModel中的數據屬性相關聯,並允許通過用戶界面直接操作數據項。
但並非一切都是財產。有時ViewModels會根據用戶與可視元素的交互來公開必須從View調用的公共方法。如果沒有MVVM,您可能會從Button的Clicked事件處理程序或TapGestureRecognizer的Tapped事件處理程序中調用此類方法。在考慮這些需求時,數據綁定和MVVM的整個概念可能開始顯得無可救藥地存在缺陷。如何刪除頁面類的代碼隱藏文件
到InitializeComponent調用,如果它仍然必須從View到ViewModel進行方法調用?
不要那麼快就放棄MVVM! Xamarin.Forms支持一種功能,允許數據綁定直接從Button和TapGestureRecognizer以及其他一些元素在ViewModel中進行方法調用。這是一個稱爲命令接口或命令接口的協議。
命令接口由八個類支持:

  • Button
  • MenuItem(在第19章“集合視圖”中介紹),因此也是ToolbarItem
  • SearchBar
  • TextCell,因此也是ImageCell(也將在第19章中介紹)
  • ListView(也將在第19章中介紹)
  • TapGestureRecognizer

也可以在自己的自定義類中實現命令。
命令界面起初可能有點令人困惑。 讓我們關注Button。
Button定義了兩種方法,可以在單擊元素時通知代碼。 第一個是Clicked事件。 但您也可以使用按鈕的命令界面作爲Clicked事件的替代(或除此之外)。 該接口由Button定義的兩個公共屬性組成:

  • 類型爲System.Windows.Input.ICommand的命令。
  • 類型爲Object的CommandParameter

爲了支持命令,ViewModel必須定義ICommand類型的公共屬性,然後通過普通數據綁定將其連接到Button的Command屬性。
與INotifyPropertyChanged一樣,ICommand接口不是Xamarin.Forms的一部分。它在System.Windows.Input命名空間中定義,並在System.ObjectModel程序集中實現,該程序集是鏈接到Xamarin.Forms應用程序的.NET程序集之一。 ICommand是Xamarin.Forms支持的System.Windows.Input命名空間中唯一的類型。實際上,它是Xamarin.Forms支持的任何System.Windows命名空間中的唯一類型。
INotifyPropertyChanged和ICommand是否在.NET程序集中定義而不是Xamarin.Forms,這是巧合嗎?不可以。這些界面通常用於ViewModels,一些開發人員可能已經爲一個或多個基於XAML的環境開發了ViewModel。如果在標準.NET命名空間和程序集中定義INotifyPropertyChanged和ICommand而不是在Xamarin.Forms中,那麼開發人員最容易將這些現有的ViewModel合併到Xamarin.Forms中。
ICommand接口定義了兩個方法和一個事件:

public interface ICommand
{
    void Execute(object arg);
    bool CanExecute(object arg);
    event EventHandler CanExecuteChanged;
}

爲了實現命令,ViewModel定義了一個或多個ICommand類型的屬性,這意味着該屬性是實現這兩個方法和事件的類型。然後,ViewModel中實現ICommand的屬性可以綁定到Button的Command屬性。單擊Button時,Button會像往常一樣觸發其正常的Clicked事件,但它也會調用綁定到其Command屬性的對象的Execute方法。 Execute方法的參數是設置爲Button的CommandParameter屬性的對象。
這是基本技術。但是,可能是ViewModel中的某些條件禁止在當前時間單擊按鈕。在這種情況下,應禁用Button。這是ICommand中CanExecute方法和CanExecuteChanged事件的目的。首次設置Command屬性時,Button會調用CanExecute。如果CanExecute返回false,則Button會自行禁用,並且不會生成Execute調用。 Button還爲CanExecuteChanged事件安裝了一個處理程序。此後,每當ViewModel觸發CanExecuteChanged事件時,該按鈕再次調用CanExecute以確定是否應該啓用該按鈕。
支持命令接口的ViewModel定義ICommand類型的一個或多個屬性,並在內部將此屬性設置爲實現ICommand接口的類。這節課是什麼,它是如何運作的?
如果您在Microsoft的一個基於XAML的環境中實現命令協議,那麼您將編寫自己的類來實現ICommand,或者可能使用您在Web上找到的類,或者某些MVVM工具附帶的類。有時這些類名爲CommandDelegate或類似的東西。
您可以在Xamarin.Forms應用程序的ViewModels中使用相同的類。但是,爲方便起見,Xamarin.Forms包含兩個實現ICommand的類,您可以使用它們。這兩個類簡單地命名爲Command和Command ,其中T是Execute和CanExecute的參數類型。
如果您確實在Microsoft環境和Xamarin.Forms之間共享ViewModel,則不能使用Xamarin.Forms定義的Command類。但是,您將使用類似於這些Command類的內容,因此以下討論無論如何都將適用。
Command類包括ICommand接口的兩個方法和事件,還定義了ChangeCanExecute方法。此方法導致Command對象觸發CanExecuteChanged事件,並且該設施非常方便。
在ViewModel中,您可能會爲ICommand類型的ViewModel中的每個公共屬性創建一個Command或Command 類型的對象。 Command或Command 構造函數需要一個Action對象形式的回調方法,當Button調用ICommand接口的Execute方法時,該對象被調用。 CanExecute方法是可選的,但採用的形式
返回bool的Func對象。
在許多情況下,ICommand類型的屬性是在ViewModel的構造函數中設置的,之後不會更改。因此,這些ICommand屬性通常不需要觸發PropertyChanged事件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章