在本实验中,你可以学到Prism的基础概念并应用到创建基于 Prism 类库的解决方案中,你可以以此作为创建一个WPF应用程序的起点。完成此实验之后,你将会学习到:
准备工作
本主题要求Prism 类库和Unity Application Block (Unity) 程序集:
Prism是作为源码发布的,你需要把它编译成Prism类库程序集 (Microsoft.Practices.Composite.dll, Microsoft.Practices.Composite.Presentation.dll, 和Microsoft.Practices.Composite.UnityExtensions.dll)
注意: |
本实验使用的是Unity 容器Container,但你也可以使用Managed Extensibility Framework (MEF)和Prism类库。 |
编译解决方案
实验步骤Procedures
本实验包括以下任务:
以下章节详述上述任务。
注意: |
本实验基于HelloWorld解决方案,可以通过运行文件Desktop only - Open QS - Hello World QuickStart.bat来打开它。 |
任务1:用Prism 类库创建一个解决方案
本任务中将带你窗机一个基于Prism类库的解决方案,作为一个开发WPF应用程序的起点。本解决方案包括推荐的Prism基础的实践及技术。按以下步骤来创建:
下面来创建一个外观Shell项目,外观Shell项目是一个典型基于Prism类库的项目的基础—它是一个包含了程序启动代码的WPF项目,使用了启动引导器BootStrapper,放置了典型视图的主窗体。
开始创建一个外观Shell项目
HelloWorld项目
在你的解决方案文件夹中创建一个名为Library.Desktop的项目文件夹,然后把CAL\Desktop\<Project>\bin\Debug中的程序集拷贝到上述文件夹下,包括:
注意: |
拷贝程序集时,连同xml文件一起拷贝,就可以在开发时使用程序集智能感知。 |
外观Shell窗体是基于Prism类库的应用程序的顶级窗体。窗体用于寄宿不同的UI组件来展示或填充相应的视图。也可包含通用的UI组件,如菜单和工具栏等。
外观Shell窗体展示了应用程序的整体风格。
按下列步骤来设置外观Shell窗体:
打开Shell.xaml 文件的Xaml视图, Window 根元素的下列属性:
Xaml代码如下:
< Window x:Class = " HelloWorld.Desktop.Shell "
xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "
Title = " Hello World " Height = " 300 " Width = " 300 " >
< Grid >
</ Grid >
</ Window >
区域Regions
本步骤描述怎样添加 ItemsControl 控件l 到外观Shell窗体中并连接到区域Region中。接着你就可以动态地添加区域到外观窗体中。
步骤如下:
xmlns:cal = " http://www.codeplex.com/CompositeWPF "
< Window x:Class = " HelloWorld.Desktop.Shell "
xmlns:cal = " http://www.codeplex.com/CompositeWPF "
xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "
Title = " Hello World " Height = " 300 " Width = " 300 " >
< ItemsControl Name = " MainRegion " />
</ Window >
设计视图变为如下:
带ItemsControl控件的外观Shell窗体
< ItemsControl Name = " MainRegion " cal:RegionManager.RegionName = " MainRegion " />
注意:启动外观窗体之后,WPF会解析附加属性cal:RegionManager.RegionName 并回调RegionManager 类。回调会创建一个与 ItemsControl 控件相关的区域。
启动引导器Bootstrapper
启动引导器Bootstrapper 负责初始化一个基于Prism类库构建的应用程序。包括 UnityBootstrapper 和MefBootstrapper 两张引导器类, 他们实现了大多数必要的功能用于使用Unity 或MEF 来作为你程序中的容器。当你使用Unity 或MEF之外的容器,你就要自己实现对应的启动引导器。
按如下步骤设置启动引导器BootStrapper。
using System.Windows;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.UnityExtensions;
using Microsoft.Practices.Unity;
添加继承关系
Class Bootstrapper : UnityBootstrapper
{
}
protected override DependencyObject CreateShell()
{
return new Shell();
}
注意: |
返回的外观对象将UnityBootstrapper基类附加到区域管理器服务中。区域管理器服务是一个包含在 Prism中用于管理区域的服务。把区域管理器实例附加到外观窗体中, 你可显式注册Region到XAML 代码,然后它可以显示在外观窗体或视图中。 |
protected override void InitializeShell()
{
base .InitializeShell();App.Current.MainWindow = (Window) this .Shell;App.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
base .ConfigureModuleCatalog();
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base .OnStartup(e);
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
}
打开文件App.xaml 移除属性StartupUri,因为我们已经在外观窗口通过Bootstrapper手动实例化了Shell窗口,就不需要该属性了。代码如下:
< Application x:Class = " HelloWorld.Desktop.App "
xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml " >
< Application.Resources >
</ Application.Resources >
</ Application >
生成然后运行应用程序,就可以看到一个空的HelloWorld窗体,如下图所示。
Helloworld窗体
任务2: 添加模块
本任务中将添加一个模块到解决方案中,按如下步骤进行:
参照下列步骤来创建模块:
带HelloWorldModule模块项目的解决方案
using Microsoft.Practices.Composite.Modularity;
public class HelloWorldModule : IModule
{
}
public void Initialize()
{
}
本步骤主要用于组织解决方案中的文件;这对一个包含很多老旧文件的项目来说是必要的。然后继续添加:
HelloWorldModule解决方案
到目前为止,我们创建了一个基于Prism类库的并且带一个模块项目的解决方案。但模块还未加载到应用程序当中,下面的章节来继续讲述如何加载模块项目和Prism中的模块。
应用程序生命周期中的模块
在应用程序启动过程中,模块经过了三步处理:
构建模块目录
TPrism类库提供了几种构建模块目录的方式。可以通过代码方式、 XAML 文件、配置文件或者通过一个文件夹来实现。下面讲述如何通过代码的方式来构建模块目录。
protected override void ConfigureModuleCatalog()
{
base .ConfigureModuleCatalog();
}
ModuleCatalog类以代码的方式定义应用程序模块—实现的内容包括实现IModuleCatalog 接口并添加一个AddModule方法手动注册模块以便在应用程序中加载模块。代码如下:
public ModuleCatalog AddModule(Type moduleType,InitializationMode initializationMode,params string [] dependsOn)
AddModule 方法同样返回模块目录实例和如下参数:
protected override void ConfigureModuleCatalog()
{
base .ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog) this .ModuleCatalog;
moduleCatalog.AddModule( typeof (HelloWorldModule.HelloWorldModule));
}
注意: |
本例中模块直接被Shell项目引用。 这使得可以用typeof(Module)来添加模块到目录中。但是在模块类型暂时无效时模块也可以被加载到目录中。 在没有指定特定的初始化模式时,WhenAvailable初始化模式是默认模式。 |
任务3: 添加视图
本任务将添加一个视图到HelloWorldModule 模块中。视图 Views 是指包含可视化内容的对象。视图Views 通常是用户控件,但也不是必须。 按如下步骤来添加视图:
下面描述如何创建一个视图View
< UserControl x:Class = " HelloWorldModule.Views.HelloWorldView "
xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml " >
< Grid >
< TextBlock Text = " Hello World " Foreground = " Green "HorizontalAlignment = " Center " VerticalAlignment = " Center "FontFamily = " Calibri " FontSize = " 24 " FontWeight = " Bold " ></ TextBlock >
</ Grid >
</ UserControl >
注意: |
本实验为求简单,没有用 Model-View-ViewModel模式来创建视图。 |
区域管理器Region Manager
区域管理器服务负责维护区域的集合,为控件创建新区域。该服务实现了Microsoft.Practices.Composite.Regions.IRegionManager 接口。 一般,我们直接与服务进行交互,以解耦的方式按名称来定位区域,并添加视图到区域中。默认情况下,UnityBootstrapper在应用程序容器中注册一个服务的实例。就是说你在HelloWorld应用程序中以依赖注入的方式获得一个到区域管理器服务的引用。
下面的步骤解释了如何获取区域管理器的实例,然后添加一个HelloWorldView视图 到外观Shell窗体的主区域main Region。
如下所示:
using Microsoft.Practices.Composite.Regions;
private readonly IRegionManager regionManager;
public HelloWorldModule(IRegionManager regionManager)
{
this .regionManager = regionManager;
}
public void Initialize()
{
regionManager.RegisterViewWithRegion( " MainRegion " , typeof (Views.HelloWorldView));
}
在前述代码中用于UI构成的方法称为视图发现。使用该方法时,你需要指定视图和视图将被加载的区域。创建好一个区域之后,它会自动查找并加载相关的视图。
注意: |
区域名必须与定义在区域中的属性RegionName值一致。 |