WPF Step By Step 系列-Prism框架在项目中使用

WPF Step By Step 系列-Prism框架在项目中使用

回顾

上一篇,我们介绍了关于控件模板的用法,本节我们将继续说明WPF更加实用的内容,在大型的项目中如何使用Prism框架,并给予Prism框架来构建基础的应用框架,并且如何来设计项目的架构和模块,下面我们就来一步步开始吧。

本文大纲

1、Prism框架下载和说明

2、Prism项目预览及简单介绍。

3、Prism框架如何在项目中使用。

Prism框架下载和说明

Prism框架是针对WPF和Silverlight的MVVM框架,这个大家应该之前,都有所耳闻,关于该框架的具体说明,可以参考如下地址:

Prism框架下载

Prism框架通过功能模块化的思想,来讲复杂的业务功能和UI耦合性进行分离,通过模块化,来最大限度的降低耦合性,很适合我们

进行类似插件话的思想来组织系统功能。并且模块之间,通过发布和订阅事件来完成信息的通信。而且其开放性支持多种框架集成。

Prism项目预览及简单介绍

框架下载完毕后,解压后的文件的组织模式如下:

我们先打开Hello World QuickStart.bat看看

上面是项目的组织结构,关于该项目内部的代码结构和写法,我们来一一分析和解释。

A、先看看HelloworldModule的代码和内容。

Views文件夹中包含了UI视图界面内容。

其中只是包含了一个Textbox文本控件,其他没有太多的内容。

接着看看该设计文件对应的后台cs文件中的代码。

也是没有什么特别的内容。接着我们看看Module中的内容代码:

上面对于Module中的代码,我们就简单的分析完毕了,当然这个模块没有办法独立的运行,我们肯定要将模块加载到宿主或某个控制的主界面中,把它显示出来即可,下面我们就来看看Prism最关键的部分。

B、宿主或主界面。

先看看APP文件

设计视图中未指定,那么肯定是在cs文件中的某处直接或简介指定。

果然,这里采用了BootStrapper来完成Run方法,实现应用的启动,我们可以来深挖,看看该文件中都包含什么内容。

接着,我们来看看Shell中的内容:

我们在来看看shell里面有没有什么特殊的代码,打开后台cs文件

并无任何特殊的内容。所以我们可以大概的了解到了Prism的运行机制和流程,那么运行后的效果如下:

符合预期的目标,下面我们将继续深入的挖掘Prism的强大之处。

Prism框架如何在项目中使用

Prism是一个强大的Mvvm框架,下面我们将重点讲解如何在项目使用Prism提供的基础功能,完成基于MVVM的WPF项目的框架设计和开发,包括应用程序的架构。

项目的解决方案结构,项目采用Prism作为UI框架,NHiberia+Unity作为ORM和IOC框架。

下面我们就来一步步解析项目中的每个部分的细节和最终项目如何把这些细节组织起来的做一个整体结构上的说明。关于其他的分层设计结构我就不多说了,只关注Prism部分的内容。

1、关于对Prism的基础封装

为什么不直接使用Prism,我们希望开发人员的学习成本更低,所以,我们队Prism的一些方法进行了封装,更符合开发人员之前熟悉的MVVM模式。

关于封装的具体内容,我们后续会看到代码。

2、关于Infrastructure基础设施层定义

3、具体的模块定义

4、看看程序应用宿主的定义:

通过上面,我们介绍了基础的项目和具体的模块和宿主模块的定义,下面我们就来详细的分析下Prism如何加载模块的并且模块间如何通信,如何完成业务功能的完整流程:

在之前介绍HelloWorld的时候,我们有简单的介绍了Prism的基本流程是宿主会在Bootstrappter中对模块进行装载并初始化,下面我们来看看我们在我给出的例子中的具体过程。

a、Shell的定义:

与之前的区别就是在于,我们原来是手写的字符串,这里通过单独的类定义成静态的常量成员,我们能够防止名称出错的可能。同时我们也可以避免因为某处界面上 Region符号的变化,因为某处没有修改,而造成不同步,运行出错的情况的发生,更容易统一的管理。具体的基础设施层中关于RegionType的定义 如下:

接着查看Shell的后台cs代码:

 1     /// <summary>
 2     /// MainWindow.xaml 的交互逻辑
 3     /// </summary>
 4     [Export]
 5     public partial class Shell : Window
 6     {
 7         public Shell()
 8         {
 9             InitializeComponent();
10         }
11
12         /// <summary>
13         /// 设置ViewModel
14         /// </summary>
15         /// <remarks>
16         /// This set-only property is annotated with the <see cref="ImportAttribute"/> so it is injected by MEF with
17         /// the appropriate view model.
18         /// </remarks>
19         [Import]
20         [SuppressMessage("Microsoft.Design", "CA1044:PropertiesShouldNotBeWriteOnly", Justification = "Needs to be a property to be composed by MEF")]
21         ShellViewModel ViewModel
22         {
23             set
24             {
25                 this.DataContext = value;
26                 if (this.DataContext != null)
27                 {
28                     ((ShellViewModel)this.DataContext).OnStatusChanged += new Action<string>(SystemStatusManagementEventHandler);
29                 }
30             }
31         }
32
33         public void SystemStatusManagementEventHandler(string parameter)
34         {
35             if (parameter.IsNullOrEmpty())
36             {
37                 throw new ArgumentNullException("无法完成操作");
38             }
39
40             switch (parameter)
41             {
42                 case HM_EMSTS.WorkStation.Infrastructure.MenuParams.Max:
43                     this.WindowState = System.Windows.WindowState.Maximized;
44                     break;
45                 case HM_EMSTS.WorkStation.Infrastructure.MenuParams.Min:
46                     this.WindowState = System.Windows.WindowState.Minimized;
47                     break;
48                 case HM_EMSTS.WorkStation.Infrastructure.MenuParams.Close:
49                     if (MessageBox.Show("是否退出系统?", "退出系统?", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK)
50                     {
51                         this.Close();
52                     }
53                     break;
54             }
55         }
56     }

上面的代码中采用了MEF中的Export特性和Import特性。 关于MEF的内容,我这里就不多介绍了,不是很了解的可以谷歌或百度下。

继续,我们查看Shell的ViewModel定义,因为上面的后台的cs代码中有订阅相关的事件。

 1    [Export(typeof(ShellViewModel))]
 2    public class ShellViewModel : HM_EMSTS.WorkStation.UICommon.NotifyBaseObject
 3    {
 4        public Action<string> OnStatusChanged;
 5
 6        [ImportingConstructor]
 7        public ShellViewModel(IEventAggregator eventAggregator)
 8        {
 9            //注册事件
10            if (eventAggregator == null)
11            {
12                throw new ArgumentNullException("eventAggregator");
13            }
14
15            eventAggregator.GetEvent<HM_EMSTS.WorkStation.Infrastructure.Events.SystemStatusManagementEvent>().Subscribe(this.SystemStatusManagementEventHandler);
16        }
17
18        public void SystemStatusManagementEventHandler(string parameter)
19        {
20            if (parameter.IsNullOrEmpty())
21            {
22                throw new ArgumentNullException("无法完成操作");
23            }
24
25            if (OnStatusChanged != null)
26                OnStatusChanged(parameter);
27        }
28    }

上面的代码,主要是为了完成对事件的订阅,并且当收到订阅的事件时,通知出去。这里特别注意,可以参考下图:

关于Event的定义我们可以看看上述Event的定义:

如果想按照,我们之前写的那样的形式来绑定和触发事件操作的话,必须这么写。

那么下面我们来看看ShellModule的定义吧,我们这里的代码如下:

我们使用了某个Module项目中的页面来替换shell中的Region。这样保证了Shell运行起来后能够正确的显示界面。

下面来看看项目中最重要的WorkStationBootstrapper的定义

前面介绍的helloWorld里面是采用的Unity容器,这里是MEF,所以要注意的部分,有所不同。这里需要制定MEF可导入导出部件所在的目录或程序集

我们知道shell后台cs的代码定义前面也说过了,有带有export标记。那么当执行上述的代码后,将会出现在MEFbootstrappter的 Container中。这里的container是CompositionContainer是MEF中定义的。

接着查看如下方法:

通过上面的几个方法,此时,我们的主程序,就完成了对Region的解析,显示出来即可。

B、模块定义:

Module主要是为了,替换Region符合和标记为具体的界面而是用的。

我们下面挑选一个页面来展示完整的定义和操作。

1、Model定义:

当我们的Model具有自动通知机制时,特别对于列表中的某个单元格的属性发生改变后,不需要刷新整个列表,这时候就会自动完成更新,WPF会自动完成。

2、IView接口定义。

因为我们这里采用MVP的设计模式,所以要求所有的View必须继承自IView接口。

我们这里都是直接定义View对应的唯一接口即可,主要是为了MEF的Export和Import时有用。

3、View的定义。

设计视图:

后台代码:

4、ViewModel的定义。

这里由于我们采用MVP模式,所有对于不同View之间的交互,我们这里放到了Presenter中,ViewModel充当的是对IView界面的完全控制抽象。

所以我们看到这里,没有任何的业务代码。但是对已IView界面所有的绑定信息,都需要定义到该类中。

5、Presenter定义。

上面讲Presenter标记了Export。主要是在Module中对Region进行映射时使用。

然后我们来看看PresenterBase的定义,一看便明白

这样在构造展示器时,我们便可以将IView和ViewModel之间的关系完成绑定。

6、Module的定义

这样我们就完成了,一个模块的功能开发,该功能模块尽量功能独立。

最终,我们通过一个主界面,将这样功能模块组装起来即可。

最终

将上面构建的模块运行下,看看效果,也许效果不是很好看,没有设置样式。

程序运行的框架还是非常的清晰,上面是工具栏,菜单栏,内容区。通过Prism我们可以讲菜单栏或者工具栏中的功能都设计成独立的模块,分别进行装载和控制,这样能够具有非常好的扩展性和可维护性。

由于本人水平有限,还存在对Prism框架不理解或理解不深刻的地方,错误之处在所难免,还请大家批评指出,谢谢!

时间: 2024-10-07 10:14:03

WPF Step By Step 系列-Prism框架在项目中使用的相关文章

ORM Nhibernate框架在项目中的配置

在项目中使用 Nhibernet 时,一定要将 配置文件 .xml  编译方式设置为 嵌入式资源,否则在运行项目时就会出现错误. 以下是hibernate.cfg.xml 的配置,在配置中使用的是 Mysql 数据库 <?xml version="1.0" encoding="utf-8" ?> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"&g

轨迹系列——记某真实项目中轨迹存储改造方案

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.    方案目标 该方案需要满足以下几点: 支持人员当天轨迹快速获取(查询). 支持轨迹高并发读.写(实际项目中轨迹高并发读情况很少). 保证所有(历史)轨迹数据的完整性.不丢失. 2.方案探讨详细描述 2.1支持轨迹快速查询--轨迹日志文件方案 海量数据高效存储.查询,这个场景本身是比较适合NoSQL数据库运用的,但是考虑到该方案实施的难度(对工程实施.维护.研发

android 项目中使用到的网络请求框架以及如何配置好接口URL

我们在做项目中一定少不了网络请求,现在很多公司的网络请求这块好多都是使用一些比较好的开源框架,我项目中使用的是volley,现在讲讲一些volley基本的使用,如果想要详细的了解就要去看它的源码了,现在贴代码讲一些它的使用了, 首先用一个类去封装下它的基本配置信息,以后需要变动的话,就直接在这里做修改,android最好能把每个功能都独立出来,这样做修改的话 不会导致出现其他的bug,特别在有新员工进入到项目组中,分配任务沟通起来也省事, ProtocolManager.java  它是一个单例

WPF Step By Step 系列 - 开篇

公司最近要去我去整理出一个完整的WPF培训的教程,我刚好将自己学习WPF的过程和经验总结整理成笔记的方式来讲述,这里就不按照书上面的东西来说了,书本上一般都是按部就班,深入浅出.我这里主要是以实战和具体的代码为准来讲述. 目前使用WPF的时间不算长,大概有2年多,比园子里很多的大师,还是会差很多.现在才刚刚算是对WPF基本的应用时掌握了,但是距离UI设计方面,还是有很大的欠缺.由于本人不太擅长美感的东西. WPF参考书推荐 下面先整理下,本人主要学习的WPF参考书: 1.WPF编程宝典(C#20

WPF MVVM 架构 Step By Step(6)(把actions从view model解耦)

到现在为止,我们创建了一个简单的MVVM的例子,包含了实现了的属性和命令.我们现在有这样一个包含了例如textbox类似的输入元素的视图,textbox用绑定来和view model联系,像点击button这样的行为用命令来联系.view model和model在内部通信. 但是在上面的架构中有一个问题,command类和view model有很严重的耦合.如果你记得command类的代码(在下面也有展示),在构造函数中传递view model对象,意味着这个command 类不能再其他的vie

C++开发WPF,Step by Step

示例代码 使用C++来开发WPF,主要是如何在MFC(Win32)的窗口中Host WPF的Page.下面我就做个详细的介绍. 一.创建工程, 由于MFC的Wizard会生成很多用不到的代码,所以我准备从一个空的工程开始创建一个MFC的工程. a)         打开VS2005,菜单File->New->Projects-, 左面选择Visual C++->Win32,右面选择Win32 Console Application,给工程起个名字CPlusPlus_WPF, Ok进入下一

WPF Step By Step 自定义模板

WPF Step By Step 自定义模板 回顾 上一篇,我们简单介绍了几个基本的控件,本节我们将讲解每个控件的样式的自定义和数据模板的自定义,我们会结合项目中的具体的要求和场景来分析,给出我们实现的方案和最终的运行效果. 本文大纲 1.控件模板及数据模板 2.ListBox深度定制模板. 3.TreeView高级模板使用实例. 控件模板及数据模板 控件模板 什么是控件模板,指定可以在控件的多个实例之间共享 Control 的可视结构和性能方面的方面.控件模板其实就是我们在可视方面的自定义模板

WPF Step By Step 控件介绍

WPF Step By Step 控件介绍 回顾 上一篇,我们主要讨论了WPF的几个重点的基本知识的介绍,本篇,我们将会简单的介绍几个基本控件的简单用法,本文会举几个项目中的具体的例子,结合这些 例子,希望我们可以对WPF的掌握会更深刻.本文涉及的内容可能较多.请大家慢慢看看.错误之处,还请指出. 本文大纲 1.基本控件介绍与用法. 基本控件介绍与用法 文本控件 Label控件 label控件:一般用户描述性文字显示. 在Label控件使用时,一般给予用户提示.用法上没有什么很特殊的,label

WPF Step By Step 完整布局介绍

WPF Step By Step 完整布局介绍 回顾 上一篇,我们介绍了基本控件及控件的重要属性和用法,我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景,当 然这些都是本人在实际项目中的使用经验,可能还存在错误之处,还请大家指出. 本文大纲 1.Grid 2.StackPanel 3.DockPanel 4.WrapPanel Grid 1.Row和Column 我们下面来介绍Grid的行的用法,及我们在UI设计过程中需要注意的细节. 由于前面我们在第一章中已经介绍了基本的关于Gr