Caliburn实现MVVM模式的编程
引言:什么是Caliburn ?
一个夜晚,一处教堂,人们忏悔结束后抬头看到一把宝剑插在一块石头上。石上字述“英格兰人,凡能从石头上拔出剑者,为王者!”,Caliburn就是英格兰人心中的石中剑,这把剑的主人是亚瑟王,但是在一次格斗中,这把剑被伯林诺王斩断。
Caliburn用于一个MVVM产品的名称,其用意明显,作者是想借助于Caliburn的“锋利”来描述这个产品。
Caliburn是一个功能全面的MVVM产品,全面的同时带来了代码量的庞大,作者在这个基础上做了一个精简版,名为 Caliburn.Micro,简写为CM。
一:Caliburn环境搭建
1,Caliburn.Micro的下载地址:https://caliburnmicro.codeplex.com/releases/view/108277,下载完成后可以看一个名为Caliburn.Micro v1.5.2 Snapshot.zip的压缩包。
随时间推移,版本有可能更新,导致名字的变化,此版本下载于2014-10-28 08:07。
2,解压过后可以看到如下目录,每个目录我做了一个简单的备注,如果做应用型开发,我们只需关注samples就够了。
点开bin目录,我们可以看到Caliburn.Micro可用于silverlight,wpf,wp的开发应用。这篇博客重点以WPF的应用来表述MVVM的用法。
二:WPF下的Caliburn.Micro理论
1:双向绑定
在做WPF下的MVVM编码时,我们先普及一个WPF的常识,在WPF中一般有双向绑定的机制,我们看到很多WPF程序的model,viewmodel都继承自INotifyPropertyChanged接口,其实这是在为双向绑定作铺垫。
PropertyChangedBase 继承自 INotifyPropertyChanged ,当我们向UI传递属性变化并且更新客户端UI时会用到INotifyPropertyChanged。
当一个集合项改变时我们则需要使用ObservableCollection<T>。
一般情况下,MVVM的ViewModel都会继承PropertyChangedBase类,以便实现双向绑定机制。
2:Action的处理
ActionMessage,利用TriggerAction的EventTrigger,可以把UI控件中的事件对应到后台方法,类似于CallMethodAction。Caliburn.Micro对ActionMessage进行了扩展,可以传入多个参数,参数支持绑定等功能。
3:Conventions的约定
Conventions,约定,只要View与ViewModel都遵守约定,就会有意想不到的效果,比如神奇的智能匹配。CM制定了一系列匹配的规则,View和ViewModel之间的匹配,控件名与属性,方法的匹配。
4:Screen
在Caliburn中,Screen用来表示UI部件,并且定义UI部件的生命周期(Activated,DeActivated等)。Conductor用来管理Screen,一个Conductor可以管理一组Screen。
三:Caliburn.Micro的引导模式
1:标准WPF程序的引导
标准的WPF的启动程序都是从设置Application结点的StartupUri属性开始的。如下代码:
<Application x:Class="WpfApplication1.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"StartupUri="MainWindow.xaml">
2:Caliburn.Micro程序的引导
Caliburn.Micro有自己的引导类,引导类主要通过Configure方法,采用MEF技术组合应用程序部件。
引导类的GetInstance,GetAllInstances,BuildUp,OnStartup方法写法比较固定。除非有特殊的需求,基本不用修改。不过要注意silverlight,wpf,wp写法上略有差异。
比如在实例化CompositionContainer容器时,silverlight用CompositionHost.Initialize方法,WPF用CompositionContainer构造函数。
在用SimpleContainer容器代替CompositionContainer容器时,应在OnStartup方法中加上DisplayRootViewFor<IShell>();这句代码。还有若干的细节问题我们可以在samples例子中慢慢品味。
public class AppBootstrapper : Bootstrapper<IShell> {private CompositionContainer _container;//用MEF组合部件protected override void Configure(){_container = new CompositionContainer(new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));//Silverlight版本//C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ComponentModel.Composition.Initialization.dll//container = CompositionHost.Initialize(// new AggregateCatalog(// AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()// )// );///如果还有自己的部件都加在这个地方CompositionBatch _batch = new CompositionBatch();_batch.AddExportedValue<IWindowManager>(new WindowManager());_batch.AddExportedValue<IEventAggregator>(new EventAggregator());_batch.AddExportedValue(_container);_container.Compose(_batch);}//根据传过来的类型和名称获取实例protected override object GetInstance(Type service, string key){string _contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;var _exports = _container.GetExportedValues<object>(_contract);if (_exports.Any()){return _exports.First();}throw new Exception(string.Format("找不到{0}实例", _contract));}//获取某一特定类型的所有实例protected override IEnumerable<object> GetAllInstances(Type service){return _container.GetExportedValues<object>(AttributedModelServices.GetContractName(service));}//将实例传递给 Ioc 容器,使依赖关系注入protected override void BuildUp(object instance){_container.SatisfyImportsOnce(instance);}protected override void OnStartup(object sender, StartupEventArgs e){base.OnStartup(sender, e);//Silverlight//Application.Current.RootVisual = new ShellView();//SimpleContainer//DisplayRootViewFor<IShell>();} }
3:设置引导类的启动
在silverlight中,启动一个引导类
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:Caliburn.Micro.Hello"x:Class="Caliburn.Micro.Hello.App"><Application.Resources><local:HelloBootstrapper x:Key="bootstrapper" /></Application.Resources> </Application>
在wpf中启动一个引导类为
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local ="clr-namespace:Calib.DWpfApp1"x:Class="Calib.DWpfApp1.App"><Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary><local:AppBootstrapper x:Key="bootstrapper" /></ResourceDictionary></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources> </Application>
四:代码实践
在xaml编程中,一般都会借助于Blend的两个类库 System.Windows.Interactivity.dll和Microsoft.Expression.Interactions.dll来进行编程。具体引用如下:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
<!--或者-->
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
此处只引用了System.Windows.Interactivity.dll类库。
<Window x:Class="Calib.DWpfApp1.MainView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"xmlns:cm="http://www.caliburnproject.org"Title="MainView" Height="500" Width="500">
a,Caliburn.Micro根据UI元素名称匹配ViewModel的方法(无参数)
<Button x:Name="OpenOneChild1" Content="打开窗口(无参)" Width="240" Height="30"/>
b,Caliburn.Micro使用Message.Attach匹配ViewModel方法(无参数)
<Button Content="打开窗口(无参)" Width="240" Height="30" cm:Message.Attach="OpenOneChild1" />
c,Caliburn.Micro借助于TriggerAction实现ViewModel方法的调用(有参数)
<Button Content="打开窗口(有参)" Width="240" Height="30"><i:Interaction.Triggers><i:EventTrigger EventName="Click"><cm:ActionMessage MethodName="OpenOneChild2"><cm:Parameter Value="hello..."></cm:Parameter></cm:ActionMessage></i:EventTrigger></i:Interaction.Triggers> </Button>
d,Caliburn.Micro使用Message.Attach匹配ViewModel方法(有参数)
<Button Content="打开窗口(有参,简写)" Width="240" Height="30" cm:Message.Attach="[Event Click] = [Action OpenOneChild2('woo~')]" />
e,Caliburn.Micro使用Message.Attach匹配多个ViewModel方法(有参数)
<Button Content="打开窗口(有参,简写,两个事件)" Width="240" Height="30" cm:Message.Attach="[Event MouseEnter] = [Action Show('Enter')];[Event MouseLeave] = [Action Show('Leave')]" />
f,cm:Action.Target 用法
<ListBox Height="100" Name="listBox1" SelectionMode="Multiple" ><ListBoxItem>这是第一项</ListBoxItem><ListBoxItem>这是第二项</ListBoxItem><ListBoxItem>这是第三项</ListBoxItem> </ListBox> <Button Content="全选" HorizontalAlignment="Left" Focusable="False" Name="button1" cm:Action.Target="{Binding ElementName=listBox1}" cm:Message.Attach="[Event Click] = [Action SelectAll]"/>
ViewModel的源码参考
[Export(typeof(IShell))] public class MainViewModel : PropertyChangedBase {readonly IWindowManager windowManager;public string MainTitle{get;private set;}[ImportingConstructor]public MainViewModel(IWindowManager wmanager){MainTitle = "主窗体-MainView";windowManager = wmanager;}public void OpenOneChild1(){ChildWindowViewModel childViewModel = new ChildWindowViewModel();windowManager.ShowDialog(childViewModel);}public void OpenOneChild2(String para1){ChildWindowViewModel childViewModel = new ChildWindowViewModel();windowManager.ShowDialog(childViewModel);}public void Show(String para1){System.Windows.MessageBox.Show(para1);} }
五:总结
近段时间接手惠普给我们公司开发的一个项目,我负责WPF程序部份,以前也断断续续的做过wpf的项目,但是用的是MVVMLight,这个项目用的是Caliburn.Micro。
帮忙“赞”一下,“赞”的高尿的远!
Caliburn实现MVVM模式的编程相关推荐
- C# WPF MVVM模式Caliburn.Micro框架下事件发布与订阅
01 - 前言 处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Caliburn提供了一种事件机制,可以在应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间 ...
- WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍...
WPF自学入门(十一)WPF MVVM模式Command命令 在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正 ...
- mvvm模式和mvc的区别_被误解的 MVC 和被神化的 MVVM,值得收藏!
MVC 的历史 MVC,全称是 Model View Controller,是模型 (model)-视图 (view)-控制器 (controller) 的缩写.它表示的是一种常见的客户端软件开发框架 ...
- 移动开发架构之MVVM模式
MVVM概念的提出和起源 MVVM是Model-View-ViewModel的简写,最早是由微软公司提出并运用,是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变 ...
- C# WPF MVVM模式Prism框架下事件发布与订阅
01 - 前言 处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Prism提供了一种事件机制,可以在应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间通过事 ...
- C# WPF MVVM模式Prism框架从零搭建(经典)
01 - 前言 目前最新的PRISM的版本是8.1.97,本节以6.3.0.0 讲解,可以在Github上获取PRISM的源码. Prism Github地址:https://github.com/P ...
- C# WPF MVVM模式下在主窗体显示子窗体并获取结果
01 - 前言 在winform中打开一个新的子窗体很简单,直接实例化窗体并show一下就可以: Form2 f2 = new Form2();f2.Show(); 或者 Form2 f2 = new ...
- 前后端分手大师——MVVM 模式
阅读目录 简而言之 组成部分 没有什么是一个栗子不能解决的 简而言之 之前对 MVVM 模式一直只是模模糊糊的认识,正所谓没有实践就没有发言权,通过这两年对 Vue 框架的深入学习和项目实践,终于可以 ...
- c# mvvm模式获取当前窗口_AWTK-MVVM 介绍
MVVM(Model-View-ViewModel)介绍 8.1 分离用户界面和业务逻辑 在开发应用程序时,要把用户界面和业务逻辑分离开来,这是每个程序员都知道的常识.分离用户界面和业务逻辑有几个重要 ...
最新文章
- Microsoft Office Communications Server 2007 R2 RTM 简体中文企业版部署速成篇之二
- Flutter+FaaS一体化任务编排的思考与设计
- 第三章:3.2 get 请求
- 解决Mysql读写分离数据延迟
- python dataframe group by_Python DataFrame.groupby()聚合函数,分组级运算
- HTML5人喜欢用来调侃自己生活状态的话
- MySQL-schema-sync 一款非常好用的 MySQL数据库同步工具
- linux 常用到的命令(centos 6.5)
- IR2104驱动原理
- 向上的箭头 html,HTML中利用div+CSS实现简单的箭头图标
- matlab二次函数拟合,【长见识】matlab的二次函数拟合
- word该值小于列表中的前一条目_文本主题发现(一)-- 数据预处理
- Java程序员两年校招笔记总结分析——菜鸡求职
- 计算机里面不显示光驱位硬盘,Windows10系统识别不了光驱位机械硬盘怎么办?解决方法...
- 规模化敏捷DevOps专业人士认证(SDP)
- mendix费用价格
- redis哨兵、集群
- 主叫号码信息识别及传送
- .netCHATING 10.4 for NET6-7.0-Crack
- 地铁和轻轨交通的特点