續上一篇對MVVM模式的簡單介紹,可以了解到MVVM需要編寫許多的自定義Command和Action之類的,而且每個類都需要設置DataContext。操作和代碼比較重復,為了減少代碼量並統一標准,需要引入MVVM框架提高效率。
開源的MVVM框架有:
PRISM:由微軟提供,和 MEF/Unity 一起用於依賴注入,支持組合命令,可以擴展。MSDN 上有詳細的教程和演練。
MVVM Light Toolkit:有 visual Studio 和 Expression Blend 的項目和項的模板。更多信息請看這里,另外可以參考 VS 和 Expression Blend 的使用教程。
Caliburn Micro:小巧但功能強大框架,支持簡化綁定,注入等,實現多種 UI 模式解決實際問題.
Simple MVVM Toolkit:提供 VS 項目和項的模板,依賴注入,支持深拷貝以及模型和視圖模型之間的屬性關聯。
Catel:包含項目和項的模板,用戶控件和企業類庫。支持動態視圖模型注入,視圖模型的延遲加載和驗證。還支持 WP7 專用的視圖模型服務。
這里我准備使用Caliburn.Micro,它很好的支持WP7.1還特別包含了專門為WP設計的Caliburn.Micro.Extensions
開源項目地址:
http://caliburnmicro.codeplex.com/
Caliburn.Micro框架的一些特點
Caliburn.Micro里面使用了很多名稱約定來實現和簡化代碼,而且提供了很多機制減少開發工作。
1. 簡化綁定
Caliburn.Micro設計了一個Binding Conventions 綁定公約,能夠簡化綁定代碼:
直接設置與綁定相同名稱的(區分大小寫)x:Name 就可以自動被綁定了
1) 簡化數據綁定:
<TextBox Text="{Binding Path=CustomerName}" />
在Caliburn.Micro中可以寫成:
<TextBox x:Name=”CustomerName” />
達到同樣的數據綁定效果,而且默認為雙向綁定。
2)簡化命令綁定:
而且同樣支持命令綁定而且更加簡化:
原來實現命令綁定的主要代碼:
public ICommand HelloCommand{ get; set; }
HelloCommand = new InvokeCommand(OnHello);
public void OnHello(){
MessageBox.Show(“Hello world”)
}
<Button Command="{Binding HelloCommand}" />
在Caliburn.Micro中可以寫成,直接與方法名相同就可以了,其余的Command可以一概不用。
<Button x:Name=”OnHello” />
3)簡化動作綁定(事件綁定):
動作綁定在Caliburn.Micro中實現了自己的ActionMessage,將原來的綁定方式:
<Button Content="Button">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<local:InvokeAction Command="{Binding HelloCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
寫為下面的方式,並設置MethodName為對應的方法名字就可以了。
<Button Content="Button">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="OnHello" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
此外還可以設置方法的參數Parameter ,使用$eventArgs可以將eventArg對象自動傳入進去。
<cal:Parameter Value="$eventArgs" />
2 自動View-ViewModel映射
不需要寫DataContext = new MainPageViewModel();之類的代碼,Caliburn.Micro可以自動完成這個映射,
只需要按照名稱約定來實現:
View全部為: {CustomName}View
ViewModel 對於的名稱: {CustomName}ViewModel
如:HelloView 就會自動映射並綁定到HelloViewModel 。
需要注意的是命名空間也是有要求的:
有2種命名空間方式可以被正確識別:
- View和ViewModel在同一名稱空間下.
- View 在Views名稱空間下,ViewModel在ViewModels名稱空間下。
3 依賴注入
因為Caliburn.Micro內部使用了IoC容器,依賴注入也是很容易的功能,這里就不詳細介紹了。
需要提示的是Caliburn.Micro在WP里面使用的是一個輕量級的PhoneContainer容器。
4 輔助接口
MVVM模式比較復雜的地方就是ViewModel之間的交互。Caliburn.Micro提供了非常多的可供注入的接口提供給
ViewModel使用。
1)INavigationService 導航服務接口:
頁面導航是WP開發的重要功能,INavigationService接口實現了封裝導航功能,並能在ViewModel里被注入使用。
首先是構造函數注入:
public MainPageViewModel(INavigationService navigationService…)
{
this.navigationService = navigationService;
}
然后直接可以導航到ViewModel,不需要知道View的相對地址:
navigationService.UriFor<ConfigViewModel>().Navigate();
當然也可以后退:
navigationService.GoBack();
2)墓碑機制和ViewModel狀態存儲和中斷恢復
我先稱贊一下,這個功能很強大!
墓碑機制是微軟Windows Phone 7手機操作系統中的一個程序運行規則。說簡單點,就是手機上一個任務被迫中斷時(如有電話打入),系統記錄下當前應用程序的狀態后,(像把事件記錄在墓碑上一樣),然后中止程序。當需要恢復時,根據“墓碑”上的內容,將程序恢復到中斷之前的狀態。這樣的一種機制就是“墓碑機制”。
不過恢復中斷狀態需要手動編寫非常麻煩,Caliburn.Micro提供了更簡單的實現,大大提高了效率。
IStorageHandler和抽象類StorageHandler<T> 可以保存和恢復ViewModel狀態,支持存儲在State或者IsolatedStorageSettings中,
使用非常方便而且能自動工作。
首先看看一個簡單ViewModel例子:
public class MainPageViewModel:Screen
{
private string hello;
public string Hello
{
get { return hello; }
set
{
hello = value;
NotifyOfPropertyChange(() => Hello);
}
}
}
根據MainPageViewModel 定義MainPageViewModelStorage類,繼承StorageHandler<MainPageViewModel>
定義完成后不用引用,Caliburn.Micro會自動工作。
public class MainPageViewModelStorage : StorageHandler<MainPageViewModel>
{
public override void Configure()
{
Id(p => p.DisplayName);
Property(model => model.Hello)
.InPhoneState()
.RestoreAfterActivation();
}
}
首先需要指定Id為ViewModel的唯一標識,這里使用Id(p => p.DisplayName)。
然后設置各個Property的存儲方式和恢復事件。
存儲方式有InPhoneState和InAppSettings。
恢復事件有RestoreAfterActivation、RestoreAfterViewLoad、RestoreAfterViewReady。
這個設置方式是不是有點像NHibernate的Map映射。
3)IWindowManager 窗體管理
可以打開自定義的Dialog或者Popup
同樣只需要知道ViewModel不需要知道View,例如:
windowManager.ShowDialog(new ConfigViewModel);
4)IEventAggregator 窗體間消息通知
實現觀察者模式和中介者模式,IEventAggregator 作為中介者從一個ViewModel向另一個訂閱消息的ViewModel發送消息對象。
在WP里面用得比較少,不過IEventAggregator 內部實現了UI線程切換有時候還是比較方便。
具體可以參考文檔:
如果需要繼續深入的學習請參考:
請學習 Caliburn.Micro v1.3 RTW\samples\ 提供的示例代碼:
特別是:
Caliburn.Micro.HelloWP71
Caliburn.Micro.HelloWindowManagerWP71
閱讀文檔:
Documentation: 詳細文檔:
http://caliburnmicro.codeplex.com/documentation
Working with Windows Phone 7 v1.1:(里面在WP項目中引入Caliburn.Micro)
園子里的一些Caliburn.Micro教程:
