第 18 章的摘要。 MVVM
注意
這本書於2016年春季出版,此後一直沒有更新。 這本書中有很多仍然有價值,但一些材料已經過時,有些主題不再完全正確或完整。
建構應用程式的最佳方式之一是將使用者介面與基礎程式代碼區隔開,有時稱為 商業規則。 有數種技術存在,但針對 XAML 型環境量身打造的技術稱為 Model-View-ViewModel 或 MVVM。
MVVM 相互關聯性
MVVM 應用程式有三個層級:
- 模型提供基礎數據,有時透過檔案或 Web 存取
- 檢視是使用者介面或呈現層,通常是在 XAML 中實作
- ViewModel 會連接模型和檢視
Model 是 ViewModel 的無知,而 ViewModel 則忽略 View。 這三個層級通常會使用下列機制彼此連線:
在許多較小的程式中,通常模型不存在,或其功能會整合到 ViewModel 中。
ViewModels 和數據系結
若要參與數據系結,ViewModel 必須能夠在 ViewModel 的屬性變更時通知 View。 ViewModel 會藉由 INotifyPropertyChanged
實作 命名空間中的 System.ComponentModel
介面來執行此作業。 這是 .NET 的一部分,而不是 Xamarin.Forms。 (一般 ViewModels 嘗試維護平台獨立性。
介面 INotifyPropertyChanged
會宣告名為 PropertyChanged
的單一事件,指出已變更的屬性。
ViewModel 時鐘
Book.Toolkit 連結庫中的 Xamarin.Forms會定義根據定時器變更的類型DateTime
屬性。 DateTimeViewModel
每當屬性變更時DateTime
,類別就會實作INotifyPropertyChanged
並引發 PropertyChanged
事件。
MvvmClock 範例會具現化此 ViewModel,並使用 ViewModel 的數據系結來顯示更新的日期和時間資訊。
ViewModel 中的互動式屬性
ViewModel 中的屬性可以更互動,如 類別所SimpleMultiplierViewModel
示範,這是 SimpleMultiplier 範例的一部分。 數據系結會從兩 Slider
個元素提供多重和乘數值,並以 來顯示產品 Label
。 不過,您可以在 XAML 中對這個使用者介面進行廣泛的變更,而不需要變更 ViewModel 或程式代碼後置檔案。
A Color ViewModel
Book.Toolkit 連結庫中的Xamarin.Forms 整合 RGB 和 HSL 色彩模型。 ColorViewModel
HslSliders 範例會示範:
簡化 ViewModel
ViewModels 中的程式碼可藉由使用 CallerMemberName
屬性來定義OnPropertyChanged
方法,以自動取得呼叫的屬性名稱來簡化。 Book.Toolkit 連結庫中的Xamarin.Forms 類別會執行這項作業,並提供 ViewModels 的基類。ViewModelBase
命令介面
MVVM 可與數據系結搭配使用,而數據系結則使用 屬性,因此在處理 Clicked
或 Tapped
的 事件Button
TapGestureRecognizer
時,MVVM 似乎不足。 若要允許 ViewModel 處理這類事件, Xamarin.Forms 支援 命令介面。
命令介面會以兩個公用屬性在 中 Button
指令清單本身:
Command
型ICommand
別的 (定義於System.Windows.Input
命名空間中)- 型別
CommandParameter
的Object
若要支援命令介面,ViewModel 必須定義型 ICommand
別的屬性,然後系結至 Command
屬性的數據 Button
。 介面 ICommand
會宣告兩個方法和一個事件:
Execute
具有型別自變數的方法object
CanExecute
具有傳回之型object
別自變數的方法bool
- 事件
CanExecuteChanged
在內部,ViewModel 會將類型的 ICommand
每個屬性設定為實作 介面之類別 ICommand
的實例。 透過數據系結, Button
一開始會呼叫 CanExecute
方法,如果方法傳 false
回 ,則會停用本身。 它也會設定事件的處理程式, CanExecuteChanged
並在引發該事件時呼叫 CanExecute
。 Button
如果已啟用 ,每當按兩下時Button
,就會呼叫 Execute
方法。
您可能有一些在 之前使用的 Xamarin.FormsViewModel,而這些模型可能已經支援命令介面。 針對只Xamarin.FormsXamarin.Forms搭配 使用的新 ViewModel,提供實Command
作 介面的ICommand
類別和Command<T>
類別。 泛型型別是 和 CanExecute
方法的自變數Execute
類型。
簡單方法執行
PowersOfThree 範例示範如何在 ViewModel 中使用命令介面。 類別 PowersViewModel
會定義 類型的 ICommand
兩個屬性,也會定義傳遞給最簡單的 Command
建構函式的兩個私用屬性。 程式包含從這個 ViewModel 到 Command
兩 Button
個專案屬性的數據系結。
元素 Button
可以輕鬆地取代為 TapGestureRecognizer
XAML 中的物件,而不需要變更程式代碼。
計算機,幾乎
AddingMachine 範例會同時使用 Execute
的 和 CanExecute
方法。ICommand
它會使用 AdderViewModel
Book.Toolkit 連結庫中的Xamarin.Forms類別。 ViewModel 包含類型為 的六個 ICommand
屬性。 這些是從的Command
建構函式和 Command
建構函式以及 的建Command<T>
構函式初始化。Command<T>
Command
新增機器的數值索引鍵全都系結至使用 Command<T>
初始化的屬性,以及 string
的自變數, Execute
並 CanExecute
識別特定索引鍵。
ViewModels 和應用程式生命週期
AdderViewModel
在 AddingMachine 範例中使用的 ,也會定義兩個名為 SaveState
和 RestoreState
的方法。 這些方法會在應用程式進入睡眠狀態,以及重新啟動時從應用程式呼叫。