WPF Prism9 模块化实战学习笔记1-框架初体验
前言
本文基于原生WPF项目一步步手动集成Prism9框架,完整实现:项目搭建、模块化拆分、MVVM架构、Region区域导航、模块解耦开发,全程记录实操步骤,适合新手入门学习Prism核心原理。
开发环境:Visual Studio 2026、.NET 10、Prism 9.0.537、DryIoc依赖注入容器
一、创建原生WPF项目
为了清晰看到每一步Prism改造细节,我们不使用Prism模板,先创建无任何框架依赖的原生WPF项目。
1.1 新建WPF应用
打开Visual Studio,选择【创建新项目】,搜索关键词WPF,选择C# WPF 应用程序。
💡 重要区分
WPF 应用程序:基于 .NET/.NET Core 现代框架(本次使用)
WPF 应用程序(.NET Framework):传统老旧框架,不推荐使用
1.2 配置项目信息
项目名称命名为PrismDemo,自定义存储路径,取消勾选【将解决方案和项目放在同一目录中】,方便后续拆分多模块、多类库。
1.3 选择框架版本
统一选择.NET 10.0 长期支持版本,保证项目版本统一,规避后续NuGet依赖冲突。
1.4 初始项目结构说明
创建完成后是纯净原生WPF工程,仅包含App.xaml、MainWindow.xaml。
二、搭建模块化架构,创建业务模块
Prism最核心的特性就是模块化开发,可以将大型项目按业务拆分多个独立模块,实现代码解耦、按需加载、团队协作开发。
2.1 创建解决方案文件夹
在解决方案右键 → 添加 → 新建解决方案文件夹,命名为Modules,用于统一管理所有业务模块类库。
2.2 创建WPF模块类库
在Modules文件夹下右键新建项目,选择WPF类库,命名为ModuleA,框架版本同样选择.NET10,与主项目保持一致。
⚠️ 注意事项
模块需要承载XAML视图页面,必须选择【WPF类库】,不能选择普通控制台类库,否则无法创建用户控件。
三、规范模块结构,引入Prism依赖
3.1 清理默认文件
删除/重命名模块默认生成的Class1.cs,后续替换为Prism模块入口类。
3.2 安装Prism核心NuGet包
右键ModuleA项目 → 管理NuGet程序包,浏览安装Prism.Wpf。
作用:提供Prism MVVM、模块接口、导航注册、事件聚合器等核心API。
3.3 规范模块目录分层
遵循标准MVVM架构,在ModuleA中创建两个核心文件夹:
Views:存放所有页面、用户控件(视图层)
ViewModels:存放视图对应业务逻辑(逻辑层)
3.4 创建视图与ViewModel
在Views文件夹添加【用户控件WPF】,命名为
UserControlA.xaml在ViewModels文件夹添加对应实体类,命名为
UserControlAViewModel.cs
四、编写模块核心代码,实现Prism模块化
4.1 模块入口类(实现IModule接口)
上文3.1重命名默认类为ModuleA.cs,实现Prism的IModule接口,完成视图导航注册。
usingPrism.Ioc;usingPrism.Modularity;usingPrism.Regions;usingModuleA.Views;namespaceModuleA{publicclassModuleA:IModule{privatereadonlyIRegionManager_regionManager;publicModuleA(IRegionManagerregionManager){_regionManager=regionManager;}// 实现接口自动生成的publicvoidOnInitialized(IContainerProvidercontainerProvider){}// 实现接口自动生成的publicvoidRegisterTypes(IContainerRegistrycontainerRegistry){// 将当前用户控件注册为可导航页面containerRegistry.RegisterForNavigation<UserControlA>();}}}4.2 编写模块视图页面
修改UserControlA.xaml,编写测试页面布局:
<UserControlx:Class="ModuleA.Views.UserControlA"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"xmlns:local="clr-namespace:ModuleA.Views"mc:Ignorable="d"d:DesignHeight="450"d:DesignWidth="800"><GridBackground="LightPink"><TextBlockText="这是模块A的内容"HorizontalAlignment="Center"VerticalAlignment="Center"FontSize="20"/></Grid></UserControl>4.3 编写ViewModel(继承BindableBase)
Prism封装了BindableBase,原生实现属性通知,替代传统INotifyPropertyChanged,简化MVVM开发。
usingPrism.Mvvm;namespaceModuleA.ViewModels{publicclassUserControlAViewModel:BindableBase{}}💡 Prism自动绑定规则
视图名:UserControlA→ 对应ViewModel:UserControlAViewModel
一定要满足命名约定,Prism才会自动绑定DataContext,无需手动配置
五、改造主项目,引用项目ModuleA,接入Prism框架
在主项目中引用项目ModuleA,点击PrismDemo项目–右键–添加–项目引用
5.1 主项目安装容器依赖
主项目PrismDemo安装NuGet包:Prism.DryIoc
Prism9不再内置容器,需手动指定DryIoc,该包已内置Prism.Wpf,无需重复安装。
5.2 改造App.xaml
将原生Application替换为PrismApplication,引入Prism命名空间:
<prism:PrismApplicationx:Class="PrismDemo.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:PrismDemo"xmlns:prism="clr-namespace:Prism.DryIoc;assembly=Prism.DryIoc"><prism:PrismApplication.Resources></prism:PrismApplication.Resources></prism:PrismApplication>5.3 改造App.xaml.cs(重写Prism生命周期)
usingPrism.DryIoc;usingPrism.Ioc;usingPrism.Modularity;usingPrismDemo.Views;usingModuleA;usingSystem.Windows;namespacePrismDemo{publicpartialclassApp:PrismApplication{// 指定程序启动主窗口protectedoverrideWindowCreateShell(){returnContainer.Resolve<MainWindow>();}// 全局服务、弹窗、共享视图注册protectedoverridevoidRegisterTypes(IContainerRegistrycontainerRegistry){}// 配置需要加载的业务模块,实现模块集成protectedoverridevoidConfigureModuleCatalog(IModuleCatalogmoduleCatalog){moduleCatalog.AddModule<ModuleA.ModuleA>();}}}5.4 主窗口定义Prism导航区域Region
修改MainWindow.xaml,定义可承载模块页面的导航区域:
<Windowx:Class="PrismDemo.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:local="clr-namespace:PrismDemo"xmlns:prism="clr-namespace:Prism.Regions;assembly=Prism.Wpf"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><DockPanel><StackPanelOrientation="Horizontal"DockPanel.Dock="Top"><ButtonContent="加载模块A"Command="{Binding LoadModuleACommand}"Margin="5"/></StackPanel><!-- Prism导航区域,名称MainRegion,用来承载模块内视图 --><ContentControlprism:RegionManager.RegionName="MainRegion"/></DockPanel></Window>5.5 主窗口ViewModel实现导航逻辑
新建MainWindowViewModel,通过IRegionManager实现页面导航:
usingPrism.Commands;usingPrism.Mvvm;usingPrism.Regions;namespacePrismDemo.ViewModels{publicclassMainWindowViewModel:BindableBase{privatereadonlyIRegionManager_regionManager;publicDelegateCommandLoadModuleACommand{get;}publicMainWindowViewModel(IRegionManagerregionManager){_regionManager=regionManager;LoadModuleACommand=newDelegateCommand(()=>{// 导航到指定区域、指定视图_regionManager.RequestNavigate("MainRegion","UserControlA");});}}}六、完整项目总体结构
、完整项目总体结构
解决方案 PrismDemo ├── 【解决方案文件夹】Modules │ └── ModuleA (WPF类库 .NET 10) │ ├── Views │ │ └── UserControlA.xaml │ ├── ViewModels │ │ └── UserControlAViewModel.cs │ └── ModuleA.cs │ └── PrismDemo (WPF主启动程序 .NET 10,Shell外壳) ├── App.xaml / App.xaml.cs ├── MainWindow.xaml / MainWindow.xaml.cs └── ViewModels └── MainWindowViewModel.cs七、项目职责与运行流程总结
7.1 项目分工
PrismDemo(Shell主外壳):程序入口、定义导航区域、统一加载所有模块、全局导航控制
ModuleA(业务模块):独立业务单元,自主注册视图,与主程序完全解耦
7.2 程序运行链路
程序启动 →
App.CreateShell()创建主窗口ConfigureModuleCatalog.AddModule<ModuleA>()加载业务模块执行
ModuleA.RegisterTypes(),注册UserControlA为导航视图界面按钮触发命令 →
IRegionManager.RequestNavigate("MainRegion", "UserControlA")Prism 在
MainRegion区域内实例化并显示模块 A 页面
八、运行结果
运行结果.gif为什么在这里不显示😭😭😭