[Prism]Composite Application Guidance for WPF(3)——创建第一个Composite WPF Application

            [Prism]Composite Application Guidance for WPF(3)——创建第一个Composite WPF Application
                                           周银辉

1.       前提条件:

你需要下载到CAL(Composite application library)库,实际上就是几个DLL文件,在项目中将会引用到他们来打造我们的程序,你可以从这里下载到它们。当然你也需要一个能打造WPF应用的IDE,比如VS2008

2.创建Shell Project

         2.1.在VS中新建一个WPF Application,将CAL库文件添加到项目引用中

         2.2.将自动生成的Window1主窗口及其相应的文件重命名为Shell,其将作为我们的Composite AppShell

         2.3.创建Bootstrapper,自定义程序初始化方式

                    新建一个Bootstrapper类,让其继承于Unity Bootstrapper,并重写其中的某些方法来实现我们的定制

    internal class Bootstrapper : UnityBootstrapper

    {

        protected override DependencyObject CreateShell()

        {

            var shell = new Shell();

            shell.Show();

            return shell;

        }

        protected override IModuleEnumerator GetModuleEnumerator()

        {           

            return new StaticModuleEnumerator();

        }

}

我们通过重写CreateShell()方法指定我们的Shell,通过重写GetModuleEnumerator()方法来指定我们的模块加载方式(这里为了编译通过,我们暂时返回一个StaticModuleEnumerator,待会会介绍如何使用配置文件来配置模块的加载)

2.4.修改程序启动方式

                    我们知道当新建一个WPF Application时,VS会在App.xaml自动生成指定StartupUri到主窗口,但这不是我们的Composite WPF Application想要的方式,我们需要从Bootstrapper启动,所以删除App.xaml自动生成指定的StartupUri,并重写App 类的构造方法:

    public partial class App

    {

        public App()

        {

            var bootStrapper = new Bootstrapper();

            bootStrapper.Run();

        }

    }

F5Shell就可以RUN起来啦

3,创建Hello World模块

         3.1.在解决方案中添加一个新的项目“HelloWorldModule”(暂且ClassLibrary类型吧)

         3.2. 添加CAL库到项目引用中,目前添加Microsoft.Practices.CompositeMicrosoft.Practices.Composite.Wpf就可以了。

         3.3.从语法层面讲,要实现一个Module,需要实现IModule接口,OK,新建一个HelloWorldModule类:

         public class HelloWorldModule : IModule

    {       

        #region IModule Members

        public void Initialize()

        {          

            System.Windows.MessageBox.Show("this is hello module");

        }

        #endregion

}

我们这里为了避免扰乱读者视线,简化一下,就上该Module 显示一个MessageBoxOK了。

4,将模块加载到Shell Project

我们可以看到Shell ProjectHelloWorld Project是完全独立的两个项目,在实际开发中,它们可能是由两个不同的Team独立开发和测试的。所以为了能在Shell中使用HelloWordCAL提供了多种方式来发现和加载模块,最简单的当然是静态加载即直接项目引用,我们这里采用配件文件的形式来实现(CAL还提供了通过扫描文件夹的方式来加载)

4.1.添加配置文件

回到Shell Project,在该项目中添加Application Configuration File,其会生成一个App.config文件,在这个文件中我们可以配置系统模块组成结构、加载顺序以及模块之间的依赖性:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

 <configSections>

    <section name="modules" type="Microsoft.Practices.Composite.Modularity.ModulesConfigurationSection, Microsoft.Practices.Composite"/>

 </configSections>

 <modules>

    <module assemblyFile="HelloWorldModule.dll" moduleType="HelloWorldModule.HelloWorldModule" moduleName="HelloWorldModule">

    </module>

 </modules>

</configuration>

4.2.指定加载方式

然后回到我们的Bootstrapper类,指定我们的模块加载方式为配置文件加载:

        protected override IModuleEnumerator GetModuleEnumerator()

        {

            var configStory = new ConfigurationStore();

            return new ConfigurationModuleEnumerator(configStory);

        }

4.3.指定模块生成位置

我们知道,模块的默认生成位置是项目的DEBUG(与RELEASE)目录,这会导致一个问题是:我们的Shell项目不知道这些模块的生成文件位置从而找不到模块文件,所以我们可以通过模块项目的Build Events中的Post-build event command line 来将生成的文件自动拷贝到Shell项目的DEBUG(或RELEASE)目录下:

xcopy "$(TargetDir)*.*" "$(SolutionDir)CAG_HelloWorld\bin\$(ConfigurationName)" /Y

(其中CAG_HelloWorldShell项目的名称)

重新生成一下项目,F5OK

5,将模块中的View注入到Shell

         在上面的示例中,我们仅仅在HelloWord模块中,显示了一个MessageBox,现在我们看看如何在其中加入一个View,并在Shell中显示出来

         5.1.在Shell中添加一个Region

                   回到Shell.xaml,在其中添加一个容器控件作为一个Region,你可以将Region看做是一个占位符,其用于放置我们的View

<Window x:Class="CAG_HelloWorld.Shell"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:cal="http://www.codeplex.com/CompositeWPF"

    Title="Shell" Height="300" Width="300">

    <Grid>

        <ItemsControl cal:RegionManager.RegionName="MainRegion"/>

    </Grid>

</Window>

         5.2.在HelloWord Project中加入HelloWorldView

                   添加一个UserControlHelloWord Project中(其实也可以是其他UI元素),在上面任意显示点什么东西,比如一个带有HelloWord字样的TextBlock。其将作为我们的View

         5.3.将View注入到Region

         这项工作是由Module在模块初始化来完成的。首先我们需要找到指定的View要注入到Region,而RegionManager提供相应的功能:

         IRegion mainRegion = regionManager.Regions["MainRegion"];

         然后我们可以将我们的View加到给Region中并激活它了:

                  var view = new HelloWorldView();

                 mainRegion.Add(view);

mainRegion.Activate(view);

         总的说来,我们的HelloWorldModule代码如下所示:

    public class HelloWorldModule : IModule

    {

        private readonly IRegionManager regionManager;

        public HelloWorldModule(IRegionManager regionManager)

        {

            this.regionManager = regionManager;

        }

        #region IModule Members

        public void Initialize()

        {

            IRegion mainRegion = regionManager.Regions["MainRegion"];

            var view = new HelloWorldView();

            mainRegion.Add(view);

            mainRegion.Activate(view);

        }

        #endregion

}

OK,至此,DEMO打造完毕,当然这step by step 的打造会让人知其然不知其所以然,但问了不混淆视线,就没有引入CAL的其他特性以及模块内部并没很好地遵循MVPMVC等模式。

posted @ 2008-07-17 14:11  周银辉  阅读(7526)  评论(8编辑  收藏  举报