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…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
