当前位置: 首页 > article >正文

.NET_Prism基本项目创建

Prism简述

  1. 模块(Module):独立的功能单元,可动态加载。
  2. 依赖注入(Dependency Injection,DI):通过 IoC 容器(如 Unity、Autofac)管理模块之间的依赖关系。(一个类型是具体的(非抽象的)并且有一个公共构造函数,容器在需要的时候就会自动创建它的实例,即使你没有显式地在容器中注册该类型)
  3. 区域管理(Region Management):使用 IRegionManager 进行动态 UI 组件加载。
  4. 事件聚合(Event Aggregator):使用 IEventAggregator 进行模块间通信。

Prism 项目创建(MVVM)

1. 安装Prism

Install-Package Prism.Unity

关于Prism.Core与Prism.Unity的关系

  • Prism.Core 是 Prism 的基础库,提供核心功能(事件聚合、命令、MVVM 基础功能等),适用于所有平台(如 WPF、Xamarin)。
  • Prism.Unity 依赖于 Prism.Core,并为 Prism 提供 Unity 依赖注入支持,模块化开发、区域管理,适用于 WPF 应用。

2. 创建启动类

2.1 修改App.xaml
① 添加命名空间xmlns:prism="http://prismlibrary.com/"
② 将标签名修改为prism:PrismApplication
③ 删除StartUri

示例代码

<prism:PrismApplication x:Class="YourApp.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:YourApp"xmlns:prism="http://prismlibrary.com/"><Application.Resources></Application.Resources>
</prism:PrismApplication>

2.2 修改App.xaml.cs
① 实现PrismApplication类
② 重写CreateShell()ConfigureModuleCatalog(IModuleCatalog moduleCatalog
③ (可选)重写RegisterTypes(IContainerRegistry containerRegistry)

注:App.xaml.cs中所做的设置均为全局设置
注:App.xaml.cs实例由WPF框架创建,无法通过构造函数依赖注入。若想获取IRegionManager可通过 var regionManager = Container.Resolve<IRegionManager>() 获取,IEventAggregator同理

示例代码

public partial class App : PrismApplication
{/*** 此处设置均为全局设置*//*** 解析并返回主窗口*/protected override Window CreateShell(){return Container.Resolve<MainWindow>();}/*** 注册服务: 依赖注入或导航* 例如: containerRegistry.Register<IMessageService, MessageService>();* 例如: containerRegistry.RegisterSingleton<IMessageService, MessageService>();* 例如: containerRegistry.RegisterForNavigation<ViewA>();* * IRegionManager与IEventAggregator已由Prism注册*/protected override void RegisterTypes(IContainerRegistry containerRegistry){}/*** 模块注册* (*  按需加载*  moduleCatalog.AddModule<ModuleA>(InitializationMode.OnDemand);*  (在其他地方)*  private readonly IModuleManager _moduleManager;*  public MyClass(IModuleManager moduleManager)*  {*      _moduleManager = moduleManager;*  }*  ......*  _moduleManager.LoadModule("ModuleA");* )*/protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog){moduleCatalog.AddModule<ModuleA>();moduleCatalog.AddModule<ModuleB>();}}

3. 创建主窗口

① 添加命名空间 xmlns:prism="http://prismlibrary.com/"
② 添加区域(Region)以动态加载View(例如:<ContentControl prism:RegionManager.RegionName="MainRegion"/>)

注:主窗口至少需要一个区域

示例代码

<Window x:Class="YourApp.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:YourApp"xmlns:prism="http://prismlibrary.com/"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><ContentControl prism:RegionManager.RegionName="MainRegion"/><ContentControl prism:RegionManager.RegionName="MessageRegion" Grid.Column="1"/></Grid>
</Window>

4. 创建模块

① 实现IModule接口
② 实现OnInitialized(IContainerProvider containerProvider)与RegisterTypes(IContainerRegistry containerRegistry)

注:模块中所做的设置仅在模块被加载时才生效

示例代码

public class ModuleA : IModule
{/*** 模块中的一切设置均局限于本模块内 仅在模块被加载时生效*/private readonly IRegionManager _regionManager;public ModuleA(IRegionManager regionManager){_regionManager = regionManager;}/*** 模块初始化逻辑*/public void OnInitialized(IContainerProvider containerProvider){// 将 ViewA 区域注入至 MainRegion(或者说将 MainRegion 的初始视图设置为 ViewA)_regionManager.RegisterViewWithRegion("MainRegion", typeof(ViewA));}/*** 注册服务: 依赖注入或导航*/public void RegisterTypes(IContainerRegistry containerRegistry){// 注册导航服务containerRegistry.RegisterForNavigation<ViewA>();containerRegistry.RegisterForNavigation<ViewB>();}
}

5. 创建View与ViewModel 

说明:
① View与ViewModel的自动绑定规则:
        View位于Views文件夹下,ViewModel位于ViewModels文件夹下
        Views文件夹与ViewModels文件夹位于同一命名空间
        ViewModel的命名为xxxViewModel(xxx为View的命名)
② BindableBase类:类继承BindableBase类后,通过SetProperty(ref _param, value)可自动处理 INotifyPropertyChange

注:propp可快捷创建使用SetProperty(ref _param, value)的属性

View示例代码

<UserControl x:Class="YourApp.Views.ViewA"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:YourApp.Views"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions><StackPanel><TextBlock Text="This is ViewA" FontSize="24" Panel.ZIndex="-1"/><TextBlock Text="{Binding Message}" FontSize="24" Panel.ZIndex="-1"/></StackPanel><Button Content="Aletr" Height="100" Width="300" FontSize="24" Command="{Binding AlertCommand}"></Button><Button Content="Change To ViewB" Command="{Binding ChangeCommand}" Height="100" Width="300" FontSize="24" Grid.Row="1" ></Button></Grid>
</UserControl>

ViewModel示例代码

public class ViewAViewModel : BindableBase
{private readonly IRegionManager _regionManager;private readonly IEventAggregator _eventAggregator;public ViewAViewModel(IRegionManager regionManager, IEventAggregator eventAggregator){_regionManager = regionManager;_eventAggregator = eventAggregator;_eventAggregator.GetEvent<MessageEvent>().Subscribe(ReceiveMessage);}public ICommand AlertCommand{get => new DelegateCommand(Alert);}public ICommand ChangeCommand{get => new DelegateCommand(Change);}private string _message = "None";public string Message{get => _message;set => SetProperty(ref _message, value);}private void Alert(){new Window().Show();}private void Change(){// 将MainRegion区域导航至ViewB_regionManager.RequestNavigate("MainRegion", "ViewB");}private void ReceiveMessage(string message){Message = message;}
}

至此基本的Prism项目就创建完成

相关文章:

.NET_Prism基本项目创建

Prism简述 模块&#xff08;Module&#xff09;&#xff1a;独立的功能单元&#xff0c;可动态加载。依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;&#xff1a;通过 IoC 容器&#xff08;如 Unity、Autofac&#xff09;管理模块之间的依赖关系。&#…...

BigEvent项目后端学习笔记(一)用户管理模块 | 注册登录与用户信息全流程解析(含优化)

&#x1f4d6; 模块概述 用户管理模块是系统的核心基础模块&#xff0c;包含 注册、登录、用户信息维护 等功能。本模块涉及 JWT Token认证、密码加密存储、文件上传 等关键技术点&#xff0c;是理解前后端分离架构中安全与数据交互的典型实践。本篇对于原项目进行了代码优化&…...

[ISP] 人眼中的颜色

相机是如何记录颜色的&#xff0c;又是如何被显示器还原的&#xff1f; 相机通过记录RGB数值然后显示器显示RGB数值来实现颜色的记录和呈现。道理是这么个道理&#xff0c;但实际上各厂家生产的相机对光的响应各不相同&#xff0c;并且不同厂家显示器对三原色的显示也天差地别&…...

解锁MySQL 8.0.41源码调试:Mac 11.6+CLion 2024.3.4实战指南

文章目录 解锁MySQL 8.0.41源码调试&#xff1a;Mac 11.6CLion 2024.3.4实战指南前期准备环境搭建详细步骤安装 CLion安装 CMake 3.30.5准备 MySQL 8.0.41 源码配置 CMake 选项构建 MySQL 项目 调试环境配置与验证配置 LLDB 调试器启动调试验证调试环境 总结与拓展 解锁MySQL 8…...

celery入门

按照Celery 官方文档&#xff0c;用 Django Celery Redis 写的一个简单项目 如需转载&#xff0c;标记出处 环境准备 1. 安装依赖 pip install django celery redis 创建 Django 项目 1. 创建 Django 项目和 APP django-admin startproject myproject cd myproject python …...

关于xcode Project navigator/项目导航栏的一些说明

本文基于 xcode12.4 版本做说明 首先要明确一点&#xff0c;导航栏这里展示的并不是当前工程在电脑硬盘中的文件结构&#xff0c;它展示的是xxxxxx.xcodeproj/project.pbxproj文件(后文简.pbxproj文件)中的内容。我们在导航栏中的操作就是修改该文件&#xff0c;有些操作会修…...

深度解析扣减系统设计:从架构到实践

背景 在当今数字化业务蓬勃发展的时代&#xff0c;扣减系统在众多业务场景中扮演着关键角色。无论是电商平台的库存扣减&#xff0c;还是金融领域的资金扣减、积分系统的积分扣减&#xff0c;一个高效、可靠且数据一致的扣减系统都是业务稳健运行的基石。本文将深入探讨扣减系…...

视觉定位项目中可以任意修改拍照点位吗?

修改拍照点位不是那么简单 1. 背景2. 修改拍照点位意味着什么&#xff1f;3. 如何解决这个问题&#xff1f; 1. 背景 在视觉定位的项目中&#xff0c;会遇到这么一种情况&#xff1a;完成三步&#xff08;9点标定&#xff0c;旋转中心标定&#xff0c;示教基准&#xff09;之…...

深度学习常用操作笔记

深度学习常用操作笔记 指令报错cannot import name Config from mmcvImportError: cannot import name print_log from mmcvImportError: cannot import name init_dist from mmengine.runnerWARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNon…...

C++学习内存管理

1.概念的介绍 总括&#xff1a; 1. 栈&#xff08;Stack&#xff09; 存储内容&#xff1a; 局部变量&#xff08;包括函数参数、非静态局部变量&#xff09;。 函数调用的上下文信息&#xff08;如返回地址、寄存器状态等&#xff09;。 特点&#xff1a; 内存由编译器自动…...

git使用。创建仓库,拉取分支,新建分支开发

文章目录 安装 git自己新建仓库&#xff0c;进行代码管理合作开发的流程拉去主分支代码查看本地分支的状态查看远程分支查看远程的仓库信息本地分支切换切换并创建分支提交代码 made by NJITZX git 是一个版本控制工具&#xff0c;真正开发项目中是多个人开发一个项目的&#…...

itsdangerous加解密源码分析|BUG汇总

这是我这两天的思考 早知道密码学的课就不旷那么多了 纯个人见解 如需转载&#xff0c;标记出处 目录 一、官网介绍 二、事例代码 源码分析&#xff1a; 加密函数dump源码使用的函数如下&#xff1a; 解密 ​编辑 ​编辑 关于签名&#xff1a; 为什么这个数字签名没有…...

常见限流算法及实现

1. 固定窗口计数器&#xff08;Fixed Window Counter&#xff09; 原理&#xff1a;在固定时间窗口&#xff08;如1分钟&#xff09;内统计请求数&#xff0c;超过阈值则拒绝后续请求。优点&#xff1a;实现简单&#xff0c;内存占用低。缺点&#xff1a;存在窗口切换时的流量…...

计算机操作系统进程(4)

系列文章目录 第二章&#xff1a;进程的描述与控制 文章目录 系列文章目录前言一、临界区的概念和描述&#xff1a;二、硬件同步机制&#xff1a; 1.关中断2.利用Test-and-Set指令实现互斥3.利用Swap指令实现进程的互斥 总结 前言 上一篇我们仅仅讲了一点关于线程同步的概念&a…...

编程题《牛牛的链表删除》的python可以用非链表的方式

描述 牛牛从键盘输入了一个长度为 n 的数组&#xff0c;把这个数组转换成链表然后把链表中所有值是 x 的节点都删除。 输入描述&#xff1a; 第一行输入两个正整数 n 和 x 表示数组的长度和要删除的链表节点值 x 。 第二行输入 n 个正整数表示数组中每个元素的值。 输出描述&am…...

Certbot实现SSL免费证书自动续签(CentOS 7版 + Docker部署的nginx)

前置安装&#xff0c;可参考Certbot实现SSL免费证书自动续签&#xff08;CentOS 7 nginx/apache&#xff09; 如果是通过 Docker 运行 Nginx&#xff0c; certbot 无法直接检测到本地的 Nginx 配置。解决方案是 使用 standalone 模式 或 挂载 Webroot 方式获取 SSL 证书&…...

C++|构造函数和析构函数

一、构造函数 构造函数是一种特殊的成员函数&#xff0c;主要用于创建对象时对对象进行初始化操作&#xff0c;即专门用于构造新对象&#xff0c;并赋值对象的成员数据。 在 C 里&#xff0c;构造函数的名称和类名相同&#xff0c;并且没有返回类型。当创建类的对象时&#x…...

AI日报 - 2025年3月17日

&#x1f31f; 今日概览&#xff08;60秒速览&#xff09; ▎&#x1f916; AGI突破 | GPT-o1在卡内基梅隆大学数学考试中获满分&#xff0c;展示AI数学能力新高度 成本仅5美分/题&#xff0c;推理速度不到1分钟 ▎&#x1f4bc; 商业动向 | Figure推出BotQ机器人制造设施&…...

不像人做的题————十四届蓝桥杯省赛真题解析(上)A,B,C,D题解析

题目A&#xff1a;日期统计 思路分析&#xff1a; 本题的题目比较繁琐&#xff0c;我们采用暴力加DFS剪枝的方式去做&#xff0c;我们在DFS中按照8位日期的每一个位的要求进行初步剪枝找出所有的八位子串&#xff0c;但是还是会存在19月的情况&#xff0c;为此还需要在CHECK函数…...

JavaScript 中 call 和 apply 的用法与区别

文章目录 前言一、 call 方法1.1 基本用法1.2 传递多个参数 二、apply 方法2.1 基本用法2.2 传递数组参数 三、call 和 apply 的区别四、实际应用场景4.1 借用方法4.2 继承与构造函数 五、总结 前言 在 JavaScript 中&#xff0c;call 和 apply 是两个非常重要的函数方法&…...

go程序调用k8s pod副本的名称IP手动赋值给configmap的参数

1、创建configmap --- apiVersion: v1 data:config.yaml: >-# config.yamlEtcd:Endpoints:- "etcd-server:2379"Username: ""Password: ""Exchanges:#- Name: "Binance"# Symbol: "BTCUSDT"# WSUrl: "wss://fstr…...

面试系列|蚂蚁金服技术面【1】

哈喽&#xff0c;大家好&#xff01;今天分享一下蚂蚁金服的 Java 后端开发岗位真实社招面经&#xff0c;复盘面试过程中踩过的坑&#xff0c;整理面试过程中提到的知识点&#xff0c;希望能给正在准备面试的你一些参考和启发&#xff0c;希望对你有帮助&#xff0c;愿你能够获…...

使用傅里叶变换测量声卡的频率失真

文章目录 一、说明二、关于声卡的技术详述三、实验代码获取四、结论 一、说明 假如我希望使用我的声卡来模拟软件无线电&#xff0c;利用声音而不是射频信号。我的声卡能胜任这项任务吗&#xff1f;本文将研究一种技术来找出答案。另外&#xff0c;需要了解音频技术的读者也可…...

Selenium 自动化测试学习总结

大概了解一下即可&#xff0c;现在主要用的自动化工具是 playWright&#xff0c;它可以录制操作。 selenium是老款自动化测试工具&#xff0c;仍有很多可取之处。 安装&#xff1a; pip install selenium即可。然后下载浏览器的驱动包&#xff0c;注意不是浏览器&#xff01;…...

【HTML5】01-HTML摆放内容

本文介绍HTML5摆放标签的知识点。 目录 1. HTML概念 2. HTML骨架 3. 标签的关系 4. 标题标签 5. 段落标签 6. 换行和水平线 7. 文本格式化标签 8. 图像标签 图像 - 属性 9. 路径 相对路径 绝对路径 10. 超链接标签 11. 音频标签 12. 视频标签 1. HTML概念 HTM…...

内存管理:

我们今天来学习一下内存管理&#xff1a; 1. 内存分布&#xff1a; 我们先来看一下我们下面的图片&#xff1a; 这个就是我们的内存&#xff0c;我们的内存分为栈区&#xff0c;堆区&#xff0c;静态区&#xff0c;常量区&#xff1b; 我们的函数栈帧开辟消耗的内存就是我们…...

设计模式使用Java案例

代码设计要有可维护性&#xff0c;可复用性&#xff0c;可扩展性&#xff0c;灵活性&#xff0c;所有要使用设计模式进行灵活设计代码 创建型 简单工厂模式&#xff08;Simple Factory&#xff09; 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;是一种创建型…...

Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南

Spring Boot拦截器&#xff08;Interceptor&#xff09;与过滤器&#xff08;Filter&#xff09;深度解析&#xff1a;区别、实现与实战指南 一、核心概念对比 1. 本质区别 维度过滤器&#xff08;Filter&#xff09;拦截器&#xff08;Interceptor&#xff09;规范层级Serv…...

模运算的艺术:从基础到高阶的算法竞赛应用

在算法竞赛中&#xff0c;模运算&#xff08;取模运算&#xff09;是一个非常重要的概念&#xff0c;尤其在处理大数、防止溢出、以及解决与周期性相关的问题时。C 中的模运算使用 % 运算符&#xff0c;但它的行为和使用场景需要特别注意。 1. 模运算的基本概念 模运算是指求一…...

Java 并发编程——Java BIO NIO Socket编程

参考Java 并发编程——Java BIO NIO Socket编程 BIO&#xff1a;阻塞式编程模型 Socket 服务端编程Socket 客户端编程 NIO&#xff1a;非阻塞式编程模型 NIO 介绍Java 中 NIO 非阻塞式与前面 BIO 阻塞式的区别Java NIO类库包含以下三个核心组件ServerSocketChannel 服务端编程…...