Prism_Moudle

因为项目需要,在研究Prism框架。。特地做个小跳转DEMO以备记忆。

Prism相关DLL下载地址:https://files.cnblogs.com/files/82767136/PrismDll.rar

 

本DEMO,功能很简单,主界面放置3个按钮,通过点击不同的按钮在右侧跳转展现不同的模块而已。

项目通过一个WPF应用程序HelloWord,作为Shell,

3个类库文件,作为模块。

一、新建WPF项目-Shell

 

Shell界面设计如下:

 

界面代码XAML:

<Window x:Class="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/prism"
    xmlns:region="clr-namespace:Prism.Regions;assembly=Prism.Wpf"
    Title="Hello World" Height="300" Width="400">
    <Grid ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <StackPanel >
            <Button Click="Button_Click" Width="100" Height="25" Margin="5">HelloWord</Button>
            <Button Click="Button_ClickA" Width="100" Height="25" Margin="5">ModuleA</Button>
            <Button Click="Button_ClickB" Width="100" Height="25" Margin="5">ModuleB</Button>
        </StackPanel>
        <Border Margin="0, 0, 0, 0"  BorderThickness="0" Grid.Column="1" >
            <ContentControl x:Name="mainContent" region:RegionManager.RegionName="MainRegion" 
                          HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0, 0, 0, 0" BorderThickness="0">
            </ContentControl>
        </Border>
    </Grid>
</Window>

后台代码:

using System.Windows;
using System;
using System.Windows.Interop;
using Prism.Regions;
using Microsoft.Practices.ServiceLocation;
using Prism.Events;
using Prism.Modularity;
using A;
using B;
using HelloWorld.Views;

namespace HelloWorld
{
    /// <summary>
    /// Interaction logic for Shell.xaml
    /// </summary>
    public partial class Shell : Window
    {
        #region [属性定义]

        /// <summary>
        /// 占位符管理器
        /// </summary>
        public IRegionManager _regionManager { get; set; }

        /// <summary>
        /// 模块管理器
        /// </summary>
        public IModuleManager _moduleManager { get; set; }


        #endregion

        public Shell()
        {
            InitializeComponent();

            this.Loaded += MainWindow_Loaded;

            //当前占位符管理器对象
            _regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();

            //当前模块管理器对象-用于管理模块加载,可以实现动态加载
            _moduleManager = ServiceLocator.Current.GetInstance<IModuleManager>();

            //IEventAggregator:事件处理接口,采用事件订阅、发布原理 通过IEventAggregator接口获取事件服务:
            /*Shell界面跳转*/
            ServiceLocator.Current.GetInstance<IEventAggregator>().GetEvent<ShellSwitchEvent>().Subscribe(ShellSwitch);

            //初始化加载
            LoadModule();

            //初始化加载HelloWord模块
            //RequestNavigate:进行页面切换
            //初始化加载首界面
            _regionManager.RequestNavigate("MainRegion", new Uri(typeof(HelloWorldModule).Name, UriKind.Relative));

        }

        private void ShellSwitch(ShellSwitchParams page)
        {
            switch (page)
            {
                case ShellSwitchParams.HelloWord:
                    {
                        _regionManager.RequestNavigate("MainRegion", new Uri(typeof(HelloWorldView).Name, UriKind.Relative));         
                        break;
                    }
                case ShellSwitchParams.ModuleA:
                    {
                        //_regionManager.RequestNavigate(RegionNames.ShellRegion, new Uri(typeof(LoginView).Name, UriKind.Relative));
                        ServiceLocator.Current.GetInstance<IRegionManager>().RequestNavigate("MainRegion", new Uri(typeof(AView).Name, UriKind.Relative));
                        break;
                    }
                case ShellSwitchParams.ModuleB:
                    {
                        ServiceLocator.Current.GetInstance<IRegionManager>().RequestNavigate("MainRegion", new Uri(typeof(BView).Name, UriKind.Relative));
                        break;
                    }
                default:
                    {
                        break;
                    }
            }
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //获取当前窗体句柄
            WindowInteropHelper wndHelper = new WindowInteropHelper(this);

            //设置当前界面风格
            BorderHelper.SetWindowNoBorder(wndHelper.Handle);
        }
        // 加载模块
        private void LoadModule()
        {
            _moduleManager.LoadModule(typeof(HelloWorldModule).Name);
            _moduleManager.LoadModule(typeof(AModule).Name);
            _moduleManager.LoadModule(typeof(BModule).Name);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ServiceLocator.Current.GetInstance<IEventAggregator>().GetEvent<ShellSwitchEvent>().Publish(ShellSwitchParams.HelloWord);
        }

        private void Button_ClickA(object sender, RoutedEventArgs e)
        {
            ServiceLocator.Current.GetInstance<IEventAggregator>().GetEvent<ShellSwitchEvent>().Publish(ShellSwitchParams.ModuleA);
        }

        private void Button_ClickB(object sender, RoutedEventArgs e)
        {
            ServiceLocator.Current.GetInstance<IEventAggregator>().GetEvent<ShellSwitchEvent>().Publish(ShellSwitchParams.ModuleB);
        }
    }
}

 

App.xaml 删除默认的启动方式,后台重写启动代码

<Application x:Class="HelloWorld.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

 

using System.Windows;

namespace HelloWorld
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        //重写启动方法
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            Bootstrapper bootstrapper = new Bootstrapper();
            bootstrapper.Run();
        }
    }
}

 

其中启动精灵Bootstrapper

using System.Windows;
using Microsoft.Practices.ServiceLocation;
using System;
using System.Collections.ObjectModel;
using Prism.Modularity;
using Prism.Unity;
using A;
using B;

namespace HelloWorld
{
    /// <summary>
    /// 自定义的启动控制类,继承Prism框架
    /// UnityBootstrapper:代表底层是通过Unity作为IOC容器
    /// </summary>
    class Bootstrapper : UnityBootstrapper
    {
       
        //重写创建Shell壳对象
        protected override DependencyObject CreateShell()
        {
            return (Shell)this.Container.Resolve(typeof(Shell), "Shell");
        }

        //protected override DependencyObject CreateShell()
        //{
        //    //创建主界面UnityContainer
        //    return this.Container.Resolve<Shell>();
        //    //return ServiceLocator.Current.GetInstance<Shell>();
        //    //return (Shell)this.Container.Resolve(typeof(Shell), "Shell");
        //}

        //重写初始化Shell
        protected override void InitializeShell()
        {
            base.InitializeShell();

            //// SILVERLIGHT  
            //App.Current.RootVisual = (UIElement)this.Shell;

            //App.Current.MainWindow = (Window)this.Shell;
            //App.Current.MainWindow.Show();

            //显示主界面
            App.Current.MainWindow = (Window)this.Shell;
            App.Current.MainWindow.Show();
            /*************************
             * Module中的初始化方法Initialize,将Region占位符替换为具体的界面
             * 如果发现Shell中的出现的Region对应的占位符,就用Module中设置的字典映射,动态匹配,
             * 找到Region对应的界面,替换Shell中的指定位置。
             ******************* ****/
        }

        //重写模块创建方法
        protected override IModuleCatalog CreateModuleCatalog()
        {
            return new ModuleCatalog();
        }

        //重写配置应用模块
        protected override void ConfigureModuleCatalog()
        {
            this.ModuleCatalog.AddModule(new ModuleInfo()
            {
                ModuleName = typeof(HelloWorldModule).Name,
                ModuleType = typeof(HelloWorldModule).AssemblyQualifiedName,
                InitializationMode = InitializationMode.OnDemand
            });

            this.ModuleCatalog.AddModule(new ModuleInfo()
            {
                ModuleName = typeof(AModule).Name,
                ModuleType = typeof(AModule).AssemblyQualifiedName,
                InitializationMode = InitializationMode.OnDemand  //动态加载
            });

            this.ModuleCatalog.AddModule(new ModuleInfo()
            {
                ModuleName = typeof(BModule).Name,
                ModuleType = typeof(BModule).AssemblyQualifiedName,
                InitializationMode = InitializationMode.OnDemand
            });    
        }

        //重写容器配置
        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();
        }

    }
}

  

 跳转参数:ShellSwitchEvent

using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{/// <summary>
    /// Shell界面跳转
    /// </summary>
    public class ShellSwitchEvent : PubSubEvent<ShellSwitchParams>
    {

    }

    /// <summary>
    /// 跳转参数
    /// </summary>
    public enum ShellSwitchParams
    {
        /// <summary>
        /// HelloWord模块
        /// </summary>
        HelloWord = 1,

        /// <summary>
        /// A模块
        /// </summary>
        ModuleA = 2,

        /// <summary>
        /// B模块
        /// </summary>
        ModuleB = 3,
    }
}

窗体样式:

BorderHelper

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HelloWorld
{   /// <summary>
    /// 设置窗体边框样式。
    /// WPF 中的用法:
    /// WindowInteropHelper wndHelper = new WindowInteropHelper(this);
    /// BorderHelper.SetWindowNoBorder(wndHelper.Handle);
    /// </summary>
    public class BorderHelper
    {

        /// <summary>
        /// 带有外边框和标题的windows的样式
        /// </summary>
        public const long WS_CAPTION = 0x00C00000L;

        public const long WS_CAPTION_2 = 0X00C0000L;


        // public const long WS_BORDER = 0X0080000L;   

        /// <summary>
        /// window 扩展样式 分层显示
        /// </summary>
        public const long WS_EX_LAYERED = 0x00080000L;

        public const long WS_CHILD = 0x40000000L;


        /// <summary>
        /// 带有alpha的样式
        /// </summary>
        public const long LWA_ALPHA = 0x00000002L;

        /// <summary>
        /// 颜色设置
        /// </summary>
        public const long LWA_COLORKEY = 0x00000001L;

        /// <summary>
        /// window的基本样式
        /// </summary>
        public const int GWL_STYLE = -16;

        /// <summary>
        /// window的扩展样式
        /// </summary>
        public const int GWL_EXSTYLE = -20;



        /// <summary>   
        /// 设置窗体的样式   
        /// </summary>   
        /// <param name="handle">操作窗体的句柄</param>   
        /// <param name="oldStyle">进行设置窗体的样式类型.</param>   
        /// <param name="newStyle">新样式</param>   
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        //[DllImport("User32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 
        //  public static extern void SetWindowLong(IntPtr handle, int oldStyle, long newStyle);
        public static extern void SetWindowLong(IntPtr handle, int oldStyle, IntPtr newStyle);


        /// <summary>
        /// 获取窗体指定的样式.
        /// </summary>
        /// <param name="handle">操作窗体的句柄</param>
        /// <param name="style">要进行返回的样式</param>
        /// <returns>当前window的样式</returns>   
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        //   [DllImport("User32.dll", EntryPoint = "GetWindowLong",CallingConvention = CallingConvention.Cdecl)]
        public static extern long GetWindowLong(IntPtr handle, int style);



        /// <summary>   
        /// 设置窗体的工作区域.   
        /// </summary>   
        /// <param name="handle">操作窗体的句柄.</param>   
        /// <param name="handleRegion">操作窗体区域的句柄.</param>   
        /// <param name="regraw">if set to <c>true</c> [regraw].</param>   
        /// <returns>返回值</returns>   
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern int SetWindowRgn(IntPtr handle, IntPtr handleRegion, bool regraw);

        /// <summary>
        /// 创建带有圆角的区域.
        /// </summary>   
        /// <param name="x1">左上角坐标的X值.</param>
        /// <param name="y1">左上角坐标的Y值.</param>
        /// <param name="x2">右下角坐标的X值.</param>
        /// <param name="y2">右下角坐标的Y值.</param>
        /// <param name="width">圆角椭圆的width.</param>
        /// <param name="height">圆角椭圆的height.</param>
        /// <returns>hRgn的句柄</returns>   
        [System.Runtime.InteropServices.DllImport("gdi32.dll")]
        public static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int width, int height);



        /// <summary>   
        /// Sets the layered window attributes.   
        /// </summary>   
        /// <param name="handle">要进行操作的窗口句柄</param>   
        /// <param name="colorKey">RGB的值</param>   
        /// <param name="alpha">Alpha的值,透明度</param>   
        /// <param name="flags">附带参数</param>   
        /// <returns>true or false</returns>   
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern bool SetLayeredWindowAttributes(IntPtr handle, ulong colorKey, byte alpha, long flags);


        //=================================================================================  
        /// <summary>  
        /// 设置窗体为无边框风格  
        /// </summary>  
        /// <param name="hWnd"></param>  
        public static void SetWindowNoBorder(IntPtr hWnd)
        {
            int oldstyle = (int)BorderHelper.GetWindowLong(hWnd, BorderHelper.GWL_STYLE);

            oldstyle &= (int)(~(WS_CAPTION | WS_CAPTION_2));

            SetWindowLong(hWnd, GWL_STYLE, (IntPtr)oldstyle);

        }

        //public enum GetWindowLongFields
        //{
        //    // ...
        //    GWL_EXSTYLE = (-20),
        //    // ...
        //}

        //[Flags]
        //public enum ExtendedWindowStyles
        //{
        //    // ...
        //    WS_EX_TOOLWINDOW = 0x00000080,
        //    // ...
        //}
    }
}

这样整个主界面Shell就搭建完毕了。

接下来就是模块的编写方式,就拿模块A代码举例。

新建类库A,建立WPF用户控件A,以及AModule类文件。

 

AModule文件:

using Prism.Modularity;
using Prism.Regions;
namespace A
{
   public class AModule : IModule
    {
        private IRegionManager _regionManager;

        public AModule(IRegionManager regionManager)
        {
            this._regionManager = regionManager;
        }

        //初始化方法
        public void Initialize()
        {
            this._regionManager.RegisterViewWithRegion("MainRegion", typeof(AView));     
        }
    }
}

AView用户控件只是简单的一个文本显示而已。

<UserControl x:Class="A.AView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d"             >
    <Grid>
        <TextBlock Text="ModuleA" Foreground="Green" HorizontalAlignment="Center" 
                   VerticalAlignment="Center" FontFamily="Calibri" FontSize="24" FontWeight="Bold"></TextBlock>
    </Grid>
</UserControl>

后台无代码。

这样模块A就实现了接口模块了。

依次实现模块B和HelloWord模块即可。

posted @ 2017-02-21 12:45  浪子の无悔  阅读(432)  评论(0编辑  收藏  举报