Prism 框架 入门
一.定义Prism 是微软 Patterns Practices 团队推出的模块化 MVVM 框架专门用于 WPF/MAUI/Uno主打大型桌面 / 移动端分层解耦开发特点模块化大型项目拆分多个独立模块业务插件按需加载、团队并行开发依赖注入 DI统一管理服务、ViewModel不用手动 new 对象区域导航 Region页面容器自动管理视图切换侧边栏、主内容区、弹窗统一管理事件聚合器 EventAggregator模块之间解耦通信不用强引用MVVM 标准化内置 BindableBase、DelegateCommand不用自己实现 INotifyPropertyChanged/ICommand阶段一 手写入门DI容器第一种你自己写的业务类 → 必须手动注册否则无法注入第二种Prism 框架自带内置服务 → 已经自动注册直接注入不用管IRegionManager区域管理器你一直在用IEventAggregator事件总线IDialogService弹窗服务INavigationService导航服务运行顺序步骤 1在容器中注册你的页面App.xaml.cs步骤 2在界面上挖好坑并命名区域MainWindow.xaml步骤 3构造函数注入区域管理器MainWindow.xaml.cs步骤 4呼叫管家下达跳转命令导航触发步骤 1改造 App.xaml App.xaml.csPrism 入口原生 WPF 入口是ApplicationPrism 必须继承PrismApplication负责DI 容器初始化、注册服务、启动主窗口 Shell。App.xaml删除原有 StartupUriprism:PrismApplication x:ClassPrismDemo.App xmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:xhttp://schemas.microsoft.com/winfx/2006/xaml xmlns:prismhttp://prismlibrary.com/ Application.Resources /Application.Resources /prism:PrismApplicationApp.xaml.csusing Prism; using Prism.Ioc; using PrismDemo.Views; using System.Windows; namespace PrismDemo { public partial class App : PrismApplication { // 1. 创建主窗口Shell整个程序根窗口 protected override Window CreateShell() { // 从DI容器拿Shell窗口不要new return Container.ResolveMainShell(); } // 2. 类型注册注册窗口、视图、服务到DI容器 protected override void RegisterTypes(IContainerRegistry containerRegistry) { // 注册主窗口 containerRegistry.RegisterWindowMainShell(); // 注册页面后面Region导航用 containerRegistry.RegisterForNavigationHomeView(); // 注册全局服务单例 containerRegistry.RegisterSingletonIMessageService, MessageService(); } } }步骤 2创建根窗口 MainShell.xamlShell程序主容器Shell 是整个程序的根窗口定义 Region 区域用来放页面切换Window x:ClassPrismDemo.Views.MainShell xmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:xhttp://schemas.microsoft.com/winfx/2006/xaml xmlns:prismhttp://prismlibrary.com/ TitlePrism入门Demo Height450 Width800 Grid !-- Prism区域Name就是Region名称用来导航跳转页面 -- ContentControl prism:RegionManager.RegionNameMainRegion/ /Grid /Window阶段二 Prism的内置MVVM体系问题我们手写原生 MVVM 时每个 ViewModel 都要重复实现INotifyPropertyChanged接口、手写属性通知、手动实现ICommand命令模板代码多、容易出错Prism 已经把这些重复逻辑全部封装成了现成的基类和工具类我们只需要继承 / 调用就能快速写出标准 MVVM 代码专注业务逻辑。1. ObservableObject属性通知基类1.1 它解决什么问题原生 MVVM 中每个属性都要手写「字段判等 → 赋值 → 触发通知」三步重复度极高。ObservableObject是 Prism 提供的 ViewModel 基类它内部已经实现了INotifyPropertyChanged接口并封装了SetProperty方法一行代码完成属性赋值 自动通知。命名空间Prism.Mvvm1.2 手写 vs Prism 写法对比原生手写属性繁琐// 还要自己实现整个 INotifyPropertyChanged 接口 private string _userName; public string UserName { get _userName; set { if (_userName ! value) { _userName value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(UserName))); } } }Prism ObservableObject 写法简洁// ViewModel 只需要继承 ObservableObject public class MainViewModel : ObservableObject { private string _userName; // set 里直接调用 SetProperty public string UserName { get _userName; set SetProperty(ref _userName, value); } }1.3 SetProperty 内部做了什么SetProperty(ref 字段, 新值)自动完成 3 件事值判等新旧值相同则什么都不做避免无效的 UI 刷新字段赋值值不同则给私有字段赋新值触发通知赋值后自动触发PropertyChanged事件UI 自动更新1.4 进阶赋值后执行额外逻辑如果属性变更后需要追加操作比如联动刷新命令状态可用带回调的重载private string _password; public string Password { get _password; set SetProperty(ref _password, value, () { // 密码变更后自动刷新登录按钮的可用状态 LoginCommand.RaiseCanExecuteChanged(); }); }2. DelegateCommand 与 AsyncDelegateCommand命令封装2.1 前置认知ICommand 的本质WPF 命令必须实现ICommand接口核心是 3 个成员Execute命令执行的业务逻辑CanExecute返回 bool控制命令是否可执行按钮灰 / 可用CanExecuteChanged通知系统重新检查命令可用状态Prism 把接口实现全部封装好了同步用DelegateCommand异步用AsyncDelegateCommand。命名空间Prism.Commands2.2 DelegateCommand同步命令基础无参数命令// 1. 定义命令属性 public DelegateCommand SayHelloCommand { get; } // 2. 构造函数中初始化传入执行方法 public MainViewModel() { SayHelloCommand new DelegateCommand(SayHello); } // 3. 命令执行的业务方法 private void SayHello() { MessageBox.Show(Hello Prism!); }XAML 绑定和原生命令完全一致Button Content打招呼 Command{Binding SayHelloCommand} /带 CanExecute 的命令控制按钮可用状态比如「保存」按钮只有内容修改后才能点击public DelegateCommand SaveCommand { get; } private bool _isModified; public bool IsModified { get _isModified; set SetProperty(ref _isModified, value); } public MainViewModel() { // 第二个参数传入 CanExecute 判断方法 SaveCommand new DelegateCommand(Save, CanSave); } private void Save() { /* 保存逻辑 */ } // 返回 true 按钮可用false 按钮禁用 private bool CanSave() IsModified;注意原生写法中IsModified变化后按钮不会自动刷新状态需要手动调用SaveCommand.RaiseCanExecuteChanged()。ObservesProperty自动刷新命令状态Prism 提供ObservesProperty方法监听指定属性属性一变就自动刷新 CanExecute不用手动调用。public MainViewModel() { SaveCommand new DelegateCommand(Save, CanSave) .ObservesProperty(() IsModified); // 监听 IsModified 属性 } //支持链式监听多个属性 LoginCommand new DelegateCommand(Login, CanLogin) .ObservesProperty(() UserName) .ObservesProperty(() Password);泛型命令 DelegateCommandT如果需要给命令传参数对应 XAML 的CommandParameter用泛型版本。// 指定参数类型为 int public DelegateCommandint DeleteCommand { get; } public MainViewModel() { DeleteCommand new DelegateCommandint(Delete); } private void Delete(int id) { // 根据 id 执行删除逻辑 }XAML 传参Button Content删除 Command{Binding DeleteCommand} CommandParameter1001 /2.3 AsyncDelegateCommand:异步命令如果给DelegateCommand传async void方法会有两个问题异常无法被正常捕获容易导致程序崩溃无法跟踪执行状态不能防止重复点击AsyncDelegateCommand是 Prism 专门为异步场景封装的支持async Task方法还自带IsExecuting执行状态属性。public AsyncDelegateCommand LoadDataCommand { get; } public MainViewModel() { LoadDataCommand new AsyncDelegateCommand(LoadDataAsync); } // 执行方法是 async Task不是 async void private async Task LoadDataAsync() { await Task.Delay(2000); // 模拟耗时加载 // 加载完成后的业务逻辑 }防止重复点击常用技巧异步任务执行期间自动禁用按钮执行完自动恢复public MainViewModel() { LoadDataCommand new AsyncDelegateCommand(LoadDataAsync) .ObservesCanExecute(() IsNotLoading); } // 执行中 IsExecutingtrue → IsNotLoadingfalse → 按钮自动禁用 private bool IsNotLoading !LoadDataCommand.IsExecuting;3.CompositeCommand复合命令批量操作神器3.1应用场景上位机开发高频使用比如主界面「全部启动」按钮点击后同时启动设备 A、设备 B、设备 C 的启动命令还有「全部停止」「批量初始化」等场景。核心逻辑复合命令是一个「命令容器」多个子命令注册进去后触发复合命令时所有子命令一起执行3.2 实操步骤第一步定义全局复合命令通常放在静态类中方便各个子模块访问public static class GlobalCommands { // 全局「全部启动」复合命令 public static CompositeCommand AllStartCommand { get; } new CompositeCommand(true); // 传 true 表示监控子命令状态子命令变了自动刷新复合命令可用状态 }第二步子 ViewModel 注册命令比如设备 A 的 ViewModel 把自己的启动命令注册进去public class DeviceAViewModel : ObservableObject { public DelegateCommand StartCommand { get; } public DeviceAViewModel() { StartCommand new DelegateCommand(Start); // 注册到全局复合命令 GlobalCommands.AllStartCommand.RegisterCommand(StartCommand); } private void Start() { // 设备A启动逻辑 } }第三步主界面绑定复合命令Button Content全部启动 Command{x:Static local:GlobalCommands.AllStartCommand} /3.3 注意事项ViewModel 销毁 / 页面关闭时调用UnregisterCommand注销命令避免内存泄漏默认规则所有子命令都可执行时复合命令才可执行4. View 与 ViewModel 自动绑定命名约定4.1 作用MVVM 中 View 需要通过DataContext关联 ViewModel 才能绑定数据。如果每个页面都手动写DataContext new XXXViewModel()耦合度高也不支持依赖注入。Prism 提供ViewModelLocator视图模型定位器按照命名约定自动找到对应 ViewModel 并赋值DataContext4.2 默认命名约定遵循「约定大于配置」View 放在Views文件夹类名以View结尾如MainView.xamlViewModel 放在ViewModels文件夹类名以ViewModel结尾如MainViewModel自动配对MainView→MainViewModel4.3 开启自动绑定在 View 的 XAML 中添加附加属性即可引入 Prism 命名空间开启自动绑定Window x:ClassPrismDemo.Views.MainView xmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:xhttp://schemas.microsoft.com/winfx/2006/xaml xmlns:prismhttp://prismlibrary.com/ prism:ViewModelLocator.AutoWireViewModelTrue Title主窗口 Height450 Width800 Grid TextBox Text{Binding UserName} / /Grid /Window运行后 Prism 会自动创建MainViewModel实例赋值给当前 View 的DataContext5. 手动绑定 ViewModel 的两种方式自动绑定是主流方案特殊场景打破命名约定、自定义注入逻辑需要手动绑定常用两种方式方式一构造函数注入依赖注入方式Prism 自带依赖注入容器ViewModel 会被容器管理。在 View 的构造函数中直接注入 ViewModel 实例再赋值给DataContext。public partial class MainView : Window { public MainView(MainViewModel viewModel) { InitializeComponent(); // 把容器注入的 ViewModel 赋值给 DataContext DataContext viewModel; } }优点强类型、显式可控适合需要在 View 构造中做额外处理的场景。方式二ViewModelLocator 手动指定类型不想遵守命名约定时可强制指定 View 对应的 ViewModel 类型。Window x:ClassYourApp.Views.CustomView xmlns:prismhttp://prismlibrary.com/ xmlns:vmclr-namespace:YourApp.ViewModels prism:ViewModelLocator.AutoWireViewModelTrue prism:ViewModelLocator.ViewModelType{x:Type vm:MyCustomViewModel}

相关新闻

如何快速集成CountryPicker到iOS项目?3分钟实现国旗选择功能

如何快速集成CountryPicker到iOS项目?3分钟实现国旗选择功能

如何快速集成CountryPicker到iOS项目?3分钟实现国旗选择功能 【免费下载链接】CountryPicker CountryPicker is a custom UIPickerView subclass that provides an iOS control allowing a user to select a country from a list. It can optionally display a flag…

2026/7/12 19:03:53 阅读更多 →
鸿蒙 构建系统:构建任务(三)

鸿蒙 构建系统:构建任务(三)

在鸿蒙应用开发中,了解构建任务有助于理解编译打包的完整流程。 一、HAP基础任务流程 HAP构建任务的主要流程:依赖处理 → 资源编译 → ArkTS编译 → 打包 → 签名。 二、HSP基础任务流程 HSP构建任务的主要流程与HAP类似,但涉及动态共享…

2026/7/12 19:01:52 阅读更多 →
ARIA状态与属性实战教程:动态内容无障碍访问的完整解决方案

ARIA状态与属性实战教程:动态内容无障碍访问的完整解决方案

ARIA状态与属性实战教程:动态内容无障碍访问的完整解决方案 【免费下载链接】aria Accessible Rich Internet Applications (WAI-ARIA) 项目地址: https://gitcode.com/gh_mirrors/aria/aria ARIA(Accessible Rich Internet Applications&#xf…

2026/7/12 18:59:52 阅读更多 →

最新新闻

n8n AI Agent 安全加固手册:OAuth2.0鉴权、敏感数据脱敏、审计日志追踪——GDPR/等保2.0合规必备

n8n AI Agent 安全加固手册:OAuth2.0鉴权、敏感数据脱敏、审计日志追踪——GDPR/等保2.0合规必备

更多请点击: https://codechina.net 第一章:n8n AI Agent 安全加固全景概览 n8n 作为低代码工作流自动化平台,其 AI Agent 扩展能力日益增强,但开放接口、动态脚本执行与第三方凭证集成也显著扩大了攻击面。安全加固需覆盖运行时…

2026/7/12 20:00:06 阅读更多 →
具身智能跨模态桥梁:TVA与VLA的互补与渗透(17)

具身智能跨模态桥梁:TVA与VLA的互补与渗透(17)

前沿技术探索:AI智能体视觉(TVA,Transformer-based Vision Agent)是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术,是集深度强化学习(DRL)、卷积神经网络(CNN…

2026/7/12 19:56:05 阅读更多 →
NVIDIA-Nemotron-Labs-3-Elastic-30B-A3B-FP8:革命性3合1弹性大语言模型深度解析

NVIDIA-Nemotron-Labs-3-Elastic-30B-A3B-FP8:革命性3合1弹性大语言模型深度解析

NVIDIA-Nemotron-Labs-3-Elastic-30B-A3B-FP8:革命性3合1弹性大语言模型深度解析 【免费下载链接】NVIDIA-Nemotron-Labs-3-Elastic-30B-A3B-FP8 项目地址: https://ai.gitcode.com/hf_mirrors/nvidia/NVIDIA-Nemotron-Labs-3-Elastic-30B-A3B-FP8 NVIDIA-N…

2026/7/12 19:54:05 阅读更多 →
ProceduralDungeon高级技巧:如何自定义房间约束与生成规则

ProceduralDungeon高级技巧:如何自定义房间约束与生成规则

ProceduralDungeon高级技巧:如何自定义房间约束与生成规则 【免费下载链接】ProceduralDungeon This is an Unreal Engine 4/5 plugin to generate procedural dungeon. 项目地址: https://gitcode.com/gh_mirrors/pr/ProceduralDungeon ProceduralDungeon是…

2026/7/12 19:54:05 阅读更多 →
p5.js-svg完全指南:如何用p5.js创建高质量矢量图形

p5.js-svg完全指南:如何用p5.js创建高质量矢量图形

p5.js-svg完全指南:如何用p5.js创建高质量矢量图形 【免费下载链接】p5.js-svg SVG runtime for p5.js. 项目地址: https://gitcode.com/gh_mirrors/p5/p5.js-svg 想要在网页上创建无限缩放不失真的矢量图形吗?🎨 p5.js-svg 正是你需要…

2026/7/12 19:52:04 阅读更多 →
打破语言壁垒:如何用XUnity.AutoTranslator让任何Unity游戏说你的语言

打破语言壁垒:如何用XUnity.AutoTranslator让任何Unity游戏说你的语言

打破语言壁垒:如何用XUnity.AutoTranslator让任何Unity游戏说你的语言 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 想象一下,你刚刚下载了一款期待已久的日本角色扮演游戏&…

2026/7/12 19:52:04 阅读更多 →

日新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/12 0:03:13 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/12 0:03:14 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/12 0:03:14 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/12 0:03:13 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/12 0:03:14 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/12 0:03:14 阅读更多 →

月新闻