WP7应用开发笔记(14) 使用Caliburn Micro简化MVVM

续上一篇对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线程切换有时候还是比较方便。

具体可以参考文档:

http://caliburnmicro.codeplex.com/wikipage?title=The%20Event%20Aggregator&referringTitle=Documentation

 

 

如果需要继续深入的学习请参考:

请学习 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)

http://caliburnmicro.codeplex.com/wikipage?title=Working%20with%20Windows%20Phone%207%20v1.1&referringTitle=Documentation

 

园子里的一些Caliburn.Micro教程:

http://www.cnblogs.com/Zhouyongh/tag/Caliburn/

posted @ 2012-01-27 20:47  kiminozo  阅读(4740)  评论(7编辑  收藏  举报