WPF开发之Prism详解【内附源码】

在实际应用开发中,随着项目业务逐渐复杂,耦合度会越来越高,维护成本也会直线上升,所以解耦也变得越来越重要。Prism框架为WPF开发中解耦提供了非常便捷的应用。今天主要以一个简单的小例子,简述WPF开发中Prism框架的简单应用,如有不足之处,还请指正。

什么是Prism?

Prism是一个开源框架,用于在WPF、Xamarin Forms、Uno/Win UI等应用中创建松耦合、可维护、可测试的XAML应用程序。Prism提供了一组设计模式的实现,这些设计模式有助于编写结构良好且可维护的XAML应用程序,包括MVVM,dependency injection,commands,EventAggregator等。

Prism源码库

Prism遵守开源许可协议(MIT),目前最新版本8.1.97,可通过GitHub进行下载最新版本。https://github.com/PrismLibrary

9e8abae4a6446cdcc75a1acaea7eaff3.png

Prism优点

 Prism 设计围绕核心建筑设计原则,即关注点分离和松散耦合。这使得Prism可以提供许多好处

  • 重复使用:通过重复使用单元测试的组件,可以通过依赖性注入在运行时间轻松发现和集成,以及通过使用可在应用程序中重复使用的应用程序级功能封装模块,在应用级别实现重复使用。

  • 可扩展性:通过管理组件依赖性、使组件在运行时间更容易集成或替换为替代实现以及提供将应用程序分解为可独立更新和部署的模块的能力,帮助创建易于扩展的应用程序

  • 灵活性:Prism 有助于创建灵活的应用程序,使它们能够随着新功能的开发和集成而更容易更新

  • 团队发展:Prism 有助于最大限度地减少跨团队依赖性,并允许团队专注于不同的功能领域(如 UI 设计、业务逻辑实现和基础架构代码开发),或不同业务级别的功能领域(如简介、销售、库存或物流)。

 

模块化思想

通过对比发现,采用模块化思想进行设计,使得程序结构清晰,符合高内聚,低耦合的设计风格。

e3486b463492bb4624376509fbe30481.png3f81a61d3d32e9ba1d18b91a16fe363c.png

 

 

Prism安装

Prism可通过NuGet方案包管理器进行安装,主要安装三个Prism.Core,Prism.Unity,Prism.Wpf

 

fd03804b8341f4de862a88e2d4076124.png

创建模块和视图控件

创建WPF类库,并添加用户控件视图,并采用MVVM开发模式

602aec3cbe4fad245ad1a4606721e78c.png

f3b8c4ef91ad815d8505b430debbdfbc.png

 

数据绑定

在Prism框架中,提供了数据绑定基类Prism.Mvvm.BindableBase,可以方便的将普通属性,转换为依赖属性,简化开发中过程中的代码量。

namespace DemoPrism.Second.ViewModels
{
    internal class SecondViewModel : BindableBase
    {
        #region 属性及构造函数

        private int id;

        public int Id
        {
            get { return id; }
            set { SetProperty(ref id, value); }
        }

        /// <summary>
        /// 模块间交互
        /// </summary>
        private readonly IEventAggregator eventAggregator;

        public SecondViewModel(IEventAggregator eventAggregator)
        {
            this.eventAggregator = eventAggregator;
            this.eventAggregator.GetEvent<DemoOneEvent>().Subscribe(DemoOneRecived);
        }
        #endregion
        private void DemoOneRecived(int id)
        {
            this.Id = id;
        }
    }
}

创建Prism模块

添加Module类,并实现Prism.Modularity.IModule接口,实现接口的模块,视为可以被Prism发现并加载的模块。以DefectListModule模块为例:

namespace DemoPrism.First
{
    public class FirstModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            IRegionManager regionManager = containerProvider.Resolve<IRegionManager>();
            regionManager.RegisterViewWithRegion("FirstRegion", typeof(Views.FirstView));
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<Views.FirstView, ViewModels.FirstViewModel>();
        }
    }
}

模块配置

Prism提供了多种模块加载方式,常用的有App.config配置文件方法。

  1. 在App.config节点,添加configSections配置,增加modules节点配置

  2. modules节点主要配置需要加载的Prism模块

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <!--prism配置-->
    <section name="modules" type="Prism.Modularity.ModulesConfigurationSection, Prism.Wpf"/>
  </configSections>
  <modules>
    <!--注册模块-->
    <module assemblyFile="Modules\DemoPrism.First.dll" moduleType="DemoPrism.First.FirstModule, DemoPrism.First" moduleName="First" startupLoaded="true" />
    <module assemblyFile="Modules\DemoPrism.Second.dll" moduleType="DemoPrism.Second.SecondModule, DemoPrism.Second" moduleName="Second" startupLoaded="true" />
  </modules>
</configuration>

模块加载

模块配置好后,需要在启动的时候,加载模块。修改WPF入口启动程序,App.xaml.cs文件,继承自Prism.Unity.PrismApplication基类,并重写相关初始化

c398525cbb9efc2c9b003826d8c26de1.png

 

namespace DemoPrism
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication
    {
        //使用容器创建主窗体
        protected override Window CreateShell() => Container.Resolve<MainWindow>();


        protected override void ConfigureViewModelLocator()
        {
            base.ConfigureViewModelLocator();
        }

        protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        {
            //通过代码的方式添加模块
            //moduleCatalog.AddModule<NavigationModule.NavigationModule>();
            //将MedicineModule模块设置为按需加载
            base.ConfigureModuleCatalog(moduleCatalog);
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {

        }


        protected override IModuleCatalog CreateModuleCatalog()
        {
            ConfigurationModuleCatalog configurationModuleCatalog = new ConfigurationModuleCatalog();
            configurationModuleCatalog.Load();

            //通过Xaml配置文件读取模块加载信息

            return configurationModuleCatalog;
            //return directoryModuleCatalog;
        }

        /// <summary>
        /// 注册适配器(区域容器:Region)
        /// </summary>
        /// <param name="regionAdapterMappings"></param>
        protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
        {
            base.ConfigureRegionAdapterMappings(regionAdapterMappings);
        }
    }
}
 

区域Region

在Prism框架中,模块可以注册到导航菜单Navigation,也可以注册到区域Region,根据实际业务需要进行选择。Region可以更加方便的进行模块化布局等。在普通容器控件中,增加prism:RegionManager.RegionName=”名称”

b09774691063ba1c9ccf0cbf3c40f66e.png

<Window x:Class="DemoPrism.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:prism="http://prismlibrary.com/"
        xmlns:local="clr-namespace:DemoPrism"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <ContentControl Grid.Column="0" prism:RegionManager.RegionName="FirstRegion"></ContentControl>
        <ContentControl Grid.Column="1" prism:RegionManager.RegionName="SecondRegion"></ContentControl>
    </Grid>
</Window>

模块交互

模块与模块之间相互独立,如果需要交互,可以通过事件聚合器IEventAggregator,采用事件的订阅和发布进行通信。

事件订阅步骤:

  1. 定义事件,定义一个类,继承自Prism.Events.PubSubEvent泛型类

  2. 事件发布,通过事件聚合器的Publish方法进行发布。

  3. 事件订阅,通过事件聚合器的Subscribe进行订阅。

namespace DemoPrism.Event
{
    /// <summary>
    /// 注册事件
    /// </summary>
    public class DemoOneEvent : PubSubEvent<int>
    {

    }
}

弹出模态窗口

 在Prism框架下,弹出模态窗口,需要以下3个步骤:

  1. 在Prism框架中,页面UserControl实现弹窗功能,被弹出页面需要实现Prism.Services.Dialogs.IDialogAware接口。

  2. 注册窗口,将UserControl注册成窗口。

  3. 调用弹出服务,弹出窗口

源码下载

示例中源码下载,在公众号恢复关键词PRISM,如下所示:

2aba24b4ab074ab18316cf8cbd408d8c.png

学习编程,从关注【老码识途】开始!!!

 

  • 0
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
WPF(Windows Presentation Foundation)是一个用于创建 Windows 应用程序的框架,而 Prism 是一个基于 WPF 的框架,它提供了一组设计模式和工具,用于帮助开发人员创建可扩展、可重用和易于维护的应用程序。 在 Prism 中,ViewModel 是一个重要的组件,它的作用是将 View(即用户界面)与 Model(即数据和业务逻辑)解耦,使得两者可以独立进行开发和测试。 在 Prism 中,ViewModel 通常是一个简单的类,它实现了 INotifyPropertyChanged 接口,用于实现数据绑定。ViewModel 还包含了一些命令(Command),用于处理用户交互事件,比如按钮点击、菜单选择等。ViewModel 还可以使用服务(Service)来访问 Model,以获取或操作数据。 下面是一个简单的 ViewModel 的示例: ```csharp public class MainViewModel : BindableBase { private readonly IMyService _myService; private string _name; public string Name { get { return _name; } set { SetProperty(ref _name, value); } } private ICommand _helloCommand; public ICommand HelloCommand { get { if (_helloCommand == null) { _helloCommand = new DelegateCommand(ExecuteHelloCommand); } return _helloCommand; } } public MainViewModel(IMyService myService) { _myService = myService; } private void ExecuteHelloCommand() { string message = _myService.GetMessage(Name); MessageBox.Show(message); } } ``` 在上面的代码中,MainViewModel 包含了一个字符串属性 Name 和一个 ICommand 属性 HelloCommand。Name 属性用于将用户界面中的文本框绑定到 ViewModel 中,而 HelloCommand 则表示用户点击“Hello”按钮时要执行的命令。HelloCommand 的实现是通过调用一个服务(IMyService)来获取一条消息,然后通过 MessageBox 显示出来。 需要注意的是,MainViewModel 的构造函数中注入了一个 IMyService 接口,这个接口封装了对数据和业务逻辑的访问,使得 ViewModel 可以与具体的实现解耦。这种依赖注入的方式可以使得应用程序的组件更加松散耦合,更加易于维护和测试。 总之,ViewModel 是 WPF Prism 中非常重要的一个组件,它用于实现视图与模型之间的解耦和交互。开发人员可以使用 ViewModel 实现数据绑定、命令处理、服务访问等功能,从而创建可扩展、可重用和易于维护的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老码识途呀

写作不易,多谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值