• 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/

  • 相关阅读:
    升级系统引起的
    php curl批处理
    看《黑炮事件》想到的
    查找单链表的倒数第k个值
    python绘制树枝
    暑假第九测
    网络流24题(持续更新)
    P2657 [SCOI2009]windy数
    P3177 [HAOI2015]树上染色
    暑假第六测
  • 原文地址:https://www.cnblogs.com/kiminozo/p/2330200.html
Copyright © 2020-2023  润新知