WPF Prism框架搭建
WPF Prism框架搭建
1.引入Prism框架
在Nuget包管理器中搜索Prism,并添加到项目中

2.在项目中使用prism框架
2.1 修改app.xaml
-
删除项目中自带的StartupUri

-
修改Application节点为prism:PrismApplication
-
引入prism命名空间

<prism:PrismApplication x:Class="WpfPrismSimple.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WpfPrismSimple"xmlns:prism="http://prismlibrary.com/"><Application.Resources><ResourceDictionary><!-- 全局样式 -->...<ResourceDictionary.MergedDictionaries><!-- 样式模板 -->...</ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>
</prism:PrismApplication>
2.2 修改app.xaml.cs
- 将原继承的Application替换成PrismApplication
- 实现PrismApplication的抽象方法
CreateShellRegisterTypes
- 使用容器构建界面显示
public partial class App : PrismApplication
{protected override Window CreateShell(){return Container.Resolve<MainWindow>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){}
}
3.实现Mvvm
3.1 View和ViewModel自动关联
-
View文件必须放在Views文件夹下,ViewModel文件必须放在ViewModels文件夹下
-
ViewModel命名必须是View文件名称+ViewModel结尾
-
View文件的xaml中需要增加自动关联属性
xmlns:prism="http://prismlibrary.com/" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"
3.2 View和ViewModel手动关联
- 通过手动在App类中的RegisterTypes方法中关联View和ViewModel
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{#region 路由管理//通过RegisterForNavigation进行手动关联containerRegistry.RegisterForNavigation<MainWindow, MainWindowViewModel>();#endregion
}
4.属性绑定
- 在ViewModel中继承
Prism.Mvvm.BindableBase类,并定义一个InputText属性,用于绑定TextBox的Text属性。代码示例如下:
public class MainWindowViewModel : BindableBase
{private string _InputText;public string InputText{get { return _InputText; }set { SetProperty(ref _InputText, value); }}
}
- 在XAML中,将TextBox的Text属性绑定到ViewModel的
InputText属性
<TextBox Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
5.方法绑定
5.1使用 Command
在Button、RadioButton等有Command属性的控件使用命令,将点击事件发送到ViewModel中
<ButtonWidth="200"Height="40"Command="{Binding TextClickCommand}"Content="test click" />
/// <summary>
/// 无参命令
/// </summary>
public ICommand TestClickCommand { get; set; }public MainWindowViewModel()
{TestClickCommand = new DelegateCommand(TestClickExecuted);
}private void TestClickExecuted()
{Console.WriteLine("TestClickExecuted");
}
5.2使用 Behavior
1. 首先,在ViewModel中添加一个命令(Command)来处理TextChanged事件。定义一个实现ICommand接口的属性,并在构造函数中将其初始化为一个DelegateCommand或其他实现ICommand接口的类。
public class MainViewModel
{public ICommand TextChangedCommand { get; set; }public MainViewModel(){TextChangedCommand = new DelegateCommand<string>(TextChangedExecuted);}private void TextChangedExecuted(string text){// 处理TextChanged事件的逻辑}
}
2. 在XAML中,将TextBox的TextChanged事件绑定到ViewModel中定义的TextChangeCommand,并使用EventTrigger将事件触发绑定到Command,然后将TextBox的TextChanged事件绑定到ViewModel中的Command:
<UserControl...xmlns:i="http://schemas.microsoft.com/xaml/behaviors"...><TextBox Text="{Binding InputText}"><i:Interaction.Triggers><i:EventTrigger EventName="TextChanged"><i:InvokeCommandAction Command="{Binding TextChangedCommand}" CommandParameter="{Binding Text, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TextBox}}}" /></i:EventTrigger></i:Interaction.Triggers></TextBox></UserControl>
- 获取在ListBox使用SelectionChanged将选中项事件绑定到ViewModel:
<!-- 数据列表 --><ListBoxx:Name="listBox" ItemContainerStyle="{StaticResource NormalListBoxItem}"ItemTemplate="{StaticResource OSDDataItemTemplate}"ItemsSource="{Binding ModelList}"SelectedIndex="{Binding SelectOsdIndex}"SelectionChanged="DataList_SelectionChanged"><i:Interaction.Triggers><i:EventTrigger EventName="SelectionChanged"><i:InvokeCommandAction Command="{Binding SelectChangedCommand}" CommandParameter="{Binding ElementName=listBox, Path=SelectedItem}" /></i:EventTrigger></i:Interaction.Triggers></ListBox>
6.事件聚合器 Event Aggregator
在Prism框架中,可以使用事件聚合器(Event Aggregator)来实现多个ViewModel之间的松散耦合通信。事件聚合器允许ViewModel之间通过发布和订阅事件来进行通信,而不需要直接引用彼此,从而减少它们之间的依赖性。
以下是在Prism框架中使用事件聚合器的步骤:
- 首先,在
App.xaml.cs文件中初始化事件聚合器:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
}
- 在需要进行通信的ViewModel中,注入
IEventAggregator接口,并定义一个事件类:
public class UpdateEvent : PubSubEvent<string>
{
}public class FirstViewModel : BindableBase
{private readonly IEventAggregator _eventAggregator;public FirstViewModel(IEventAggregator eventAggregator){_eventAggregator = eventAggregator;// 订阅事件_eventAggregator.GetEvent<UpdateEvent>().Subscribe(UpdateMethod);}private void UpdateMethod(string message){// 处理事件}
}
- 在另一个ViewModel中,也注入
IEventAggregator接口,并订阅事件:
public class SecondViewModel : BindableBase
{private readonly IEventAggregator _eventAggregator;public SecondViewModel(IEventAggregator eventAggregator){_eventAggregator = eventAggregator;// 发布事件_eventAggregator.GetEvent<UpdateEvent>().Publish("Message from SecondViewModel");}
}
通过上述步骤,FirstViewModel和SecondViewModel之间可以通过事件聚合器进行松散耦合的通信。当SecondViewModel发布UpdateEvent事件时,FirstViewModel中的UpdateMethod方法会被调用,并传递消息作为参数。
这种方式可以帮助在Prism框架中实现多个ViewModel之间的通信,使它们之间更加解耦合
7.区域 Region
在Prism框架中,区域(Region)是一种特殊的控件,用于动态加载和管理视图的容器。通过使用区域,可以实现灵活的模块化设计和动态的视图切换。以下是一个简单的示例代码,演示如何在Prism框架中使用区域:
- 首先,定义一个区域控件(如ContentControl)来表示区域,在XAML文件中:
<ContentControl Name="MainRegion" prism:RegionManager.RegionName="MainRegion" />
在这个示例中,我们创建了一个名为MainRegion的区域,通过prism:RegionManager.RegionName属性来标识它。
- 然后,在ViewModel或者Module中,使用
IRegionManager接口来导航到该区域并加载视图:
public class MainViewModel : BindableBase
{private readonly IRegionManager _regionManager;public MyModule(IRegionManager regionManager){_regionManager = regionManager;}public void Initialize(){_regionManager.RegisterViewWithRegion("MainRegion", typeof(MyView));}
}
在这个示例中,我们在Initialize方法中通过_regionManager.RegisterViewWithRegion方法将MyView视图注册到名为MainRegion的区域中。
- 最后,创建并定义
MyView视图(UserControl),并对其进行需要的创建、展示和绑定等操作。
通过以上步骤,区域管理器(RegionManager)会自动加载MyView视图到MainRegion的区域中。通过Prism框架的区域机制,我们可以实现模块化设计,将应用程序拆分成多个模块,每个模块负责自己的视图和逻辑,并通过区域进行展示和管理。
希望这个简单示例对你有帮助,如果有任何问题或需要进一步的说明,请随时告诉我。
8.对话框 DialogService
在Prism框架中,DialogService是一个用于显示对话框的服务,它提供了一种方便的方式让ViewModel调用对话框而不依赖于具体的UI组件。以下是一个简单的示例代码,演示如何在Prism框架中使用DialogService来显示对话框:
- 首先,在
App.xaml.cs中注册DialogService服务:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{containerRegistry.RegisterDialog<ConfirmationDialog, ConfirmationDialogViewModel>();
}
这里我们注册了一个名为ConfirmationDialog的对话框和相应的ViewModelConfirmationDialogViewModel。
- 在需要显示对话框的ViewModel中,注入
IDialogService服务,并调用ShowDialog方法:
public class MyViewModel : BindableBase
{private readonly IDialogService _dialogService;public MyViewModel(IDialogService dialogService){_dialogService = dialogService;}public void ShowConfirmationDialog(){var result = _dialogService.ShowDialog("ConfirmationDialog", new DialogParameters(), null);if (result.Result == ButtonResult.OK){// 用户点击了确定按钮}}
}
在上述示例中,当需要显示对话框时,调用ShowDialog方法并传递对话框的名称(“ConfirmationDialog”)、参数(DialogParameters对象)和回调方法。最后根据用户操作的结果进行相应的处理。
- 创建对应的对话框视图和ViewModel:
对话框视图(如ConfirmationDialog.xaml)和ViewModel(如ConfirmationDialogViewModel.cs)。在对话框的ViewModel中实现对话框逻辑,并在需要的时候通过IDialogAware接口返回用户操作的结果。
相关文章:
WPF Prism框架搭建
WPF Prism框架搭建 1.引入Prism框架 在Nuget包管理器中搜索Prism,并添加到项目中 2.在项目中使用prism框架 2.1 修改app.xaml 删除项目中自带的StartupUri 修改Application节点为prism:PrismApplication 引入prism命名空间 <prism:PrismApplication x:C…...
MyBatisplus使用报错--Invalid bound statement
报错如下 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.lotus.mybatis.mapper.UserMapper.selectListat org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)at com.baomidou.mybatisplus.cor…...
QT-QPainter实现一个动态充电的电池
1、效果 2、核心代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer>...
【云原生】Kubernetes----Metrics-Server组件与HPA资源
目录 引言 一、概述 (一)Metrics-Server简介 (二)Metrics-Server的工作原理 (三)HPA与Metrics-Server的作用 (四)HPA与Metrics-Server的关系 (五)HPA与…...
模拟原神圣遗物系统-小森设计项目,设计圣遗物(生之花,死之羽,时之沙,空之杯,理之冠)抽象类
分析圣遗物 在圣遗物系统,玩家操控的是圣遗物的部分 因此我们应该 物以类聚 人与群分把每个圣遗物的部分,抽象出来 拿 生之花,死之羽为例 若是抽象 类很好的扩展 添加冒险家的生之花 时候继承生之花 并且名称冒险者- 生之花 当然圣遗物包含…...
仿真模拟--telnet服务两种认证模式(自作)
自己做的笔记,有问题或看不懂请见解一下~ 目录 两个路由器间实现telnet服务(password认证模式) server client 两个路由器间实现telnet服务(aaa认证模式) server client 改名 tab键补齐 不会就扣问号 ? save 两个路由器间实现telnet服务…...
Apple Phone Memory
Apple Phone Memory 苹果手机内存查询,哪些应用程序(app)占用内存: 设置 通用 iPhone储存空间 清理下QQ音乐:...
Kubernetes容器运行时:Containerd vs Docke
容器化技术笔记 Kubernetes容器运行时:Containerd vs Docke - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this arti…...
【java 线程的状态】
介绍 Java 线程在运⾏的⽣命周期中的指定时刻只可能处于下⾯ 6 种不同状态的其中⼀个状态 状态名称说明NEW初始状态,线程被构建,但是还没有调用start()方法RUNNABLE运行状态,Java线程将操作系统中的就绪和运行两种状态统称为"运行中"BLOCKED阻塞状态,表示线程阻塞于…...
php加密验签
签名生成步骤(小程序端/前端): 确定参与签名的参数:选择需要参与签名的请求参数,通常包括请求的时间戳、随机数、请求的数据等。 参数排序与拼接:将所有参与签名的参数按照字母顺序排序,并拼接成…...
【Golang - 90天从新手到大师】Day06 - 数组
系列文章合集 Golang - 90天从新手到大师 数组是golang中最常用的一种数据结构,数组就是同一类型数据的有序集合 定义一个数组 格式: var name [n]type n为数组长度,n>0 且无法修改,type为数组的元素类型如: var a [2]int上面的例子定义了一个长度为2,元素类型为int的数组…...
java的有参构造方法
java的有参构造方法和无参构造方法类似,区别是构造方法名称里后面跟着一个括号,括号里是参数的定义 示例代码如下 class student4{private String name;private int age;public student4(String n,int a) {namen;agea;System.out.println("调用了…...
Vue66-vue-默认插槽
一、默认插槽需求 1-1、原本的写法: 在每个category组件中用v-show来做条件渲染,但是不方便! 1-2、默认插槽 img标签,ul标签,video标签,都是在app组件中完成解析之后,塞到category组件中的&…...
tsf-consul的使用
在腾讯云微服务平台TSF中使用Consul作为服务发现组件,通常需要遵循以下步骤: ### 1. 创建应用 首先,您需要在TSF控制台创建一个应用。在创建应用时,选择合适的业务类型、开发语言、开发框架等信息。对于使用Consul作为服务发现组件的Spring Cloud应用,您需要选择“业务应…...
【perl】基本语法 /备忘录/
分享 perl 语言学习资源 Perl 教程|极客教程 (geek-docs.com) Perl [zh] (runebook.dev) Perl 运算符 | 菜鸟教程 (runoob.com) Perl Documentation - Perldoc Browser Search the CPAN - metacpan.org 当然还有一些经典书籍,不再列举。 1、数字 1.1、数字表…...
mongodb 集群安装
整体架构图: 1. 配置域名 Server1: OS version: CentOS Linux release 8.5.2111 hostnamectl --static set-hostname mongo01 vi /etc/sysconfig/network # Created by anaconda hostnamemong01 echo "192.168.88.20 mong1 mongo01.com mongo…...
绿茶集团重启IPO:流量渐退、业绩波动,还能讲出好故事吗?
近日,绿茶集团有限公司(下称“绿茶集团”)向港交所递交上市申请,花旗、招银国际为其联席保荐人。 回望绿茶集团的上市之路,可谓有诸多坎坷。该公司于2021年3月首度向港交所发起冲击,但却将中文版招股书中的“流动负债总额”错写成…...
Git与SSH
Git Git是一种分布式版本控制系统,最初由Linus Torvalds为管理Linux内核开发而设计并开发。Git可以帮助开发团队协作管理代码,跟踪代码变更历史,并在需要时回溯到特定版本。 分布式版本控制:每个开发者都可以拥有完整的代码仓库…...
我的创作纪念日--码农阿豪
个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] 📱…...
Git 学习笔记(超详细注释,从0到1)
Git学习笔记 1.1 关键词 Fork、pull requests、pull、fetch、push、diff、merge、commit、add、checkout 1.2 原理(看图学习) 1.3 Fork别人仓库到自己仓库中 记住2个地址 1)上游地址(upstream地址):http…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
