WPF项目实战视频《二》(主要为prism框架)

14.prism框架知识(1)

使用在多个平台的MVVM框架
新建WPF项目prismDemo
项目中:工具-NuGet包管理:安装Prism.DryIoc框架
在git中能看Prism的结构和源代码:git链接地址
例如:Prism/src/Wpf/Prism.DryIoc.Wpf/PrismApplication.cs这个类,就是在我们自己的prismDemo项目中需要更改继承使用。
在这里插入图片描述
报错:加上(更改)以下三行,重新生成并实现抽象类,上图报错即解决。
在这里插入图片描述
抽象类的实现:
在这里插入图片描述
管理扩展:添加"Prism Template Pack",就不用每次新建项目都添加一次prism了
添加扩展之后重新打开VS,新建项目:
在这里插入图片描述
打开之后就包含有prism和一些项目文件结构:
在这里插入图片描述

15.prism区域介绍(2)

主要内容:区域的概念和使用方法。
prism界面(.xaml文件中)中划分区域,可放入容器或者控件(动态的)

在.xaml中加入不同的子模块:(添加xsml子模块-主页面.png)
在这里插入图片描述

在views中新加三个用户控件:page1,page2,page3
现需要点击不同的按钮进入不同的页面:在ViewModels文件夹中修改MainWindowViewModel.cs文件:

public class MainWindowViewModel : BindableBase
{//执行不同的模块public DelegateCommand<string> OpenCommand { get; private set; }public MainWindowViewModel(){//执行不同的模块OpenCommand = new DelegateCommand<string>(Open);}private void Open(string obj){switch (obj){case "viewA": break;case "viewB": break;case "viewC": break;}}
}

绑定:.xaml中加入Content参数,进行绑定,传递参数用:CommandParameter参数

 <StackPanel Orientation="Horizontal"><Button Margin="5" Content="打开模块A" Command="{Binding OpenCommand}" CommandParameter="viewA"/><Button Margin="5" Content="打开模块B" Command="{Binding OpenCommand}" CommandParameter="viewB"/><Button Margin="5" Content="打开模块C" Command="{Binding OpenCommand}" CommandParameter="viewC"/></StackPanel><!--需要在.cs文件中连接需要使用Content--><ContentControl Grid.Row="1" Content="{Binding Body}"/>

连接的Body的使用方式:在MainWindowViewModel.cs文件中

//定义一个跟MainWindow.xaml中绑定对应的Body
private object body;
public object Body
{get { return body; }set { body = value; RaisePropertyChanged(); }
}
....
//使用:
private void Open(string obj)
{switch (obj){case "viewA": Body = new Page1(); break;	//此处使用case "viewB": Body = new Page2();  break;	//此处使用case "viewC": Body = new Page3();  break;	//此处使用}
}

(以上使用到Prism框架的自动查找上下文功能(views – viewModels))功能完成。


发现问题:view页面和viewModel后端处理,耦合性较大。需要降低耦合性------解决方式:使用prism插件:
在这里插入图片描述

在MainWindow.xaml中,需要注意prism的扩展插件自动生成了以下代码,注意不要重复添加,会报错。

<ContentControl prism:RegionManager.RegionName="ContentRegion"/>
<!--ui界面第二行内容-->
<!--需要在.cs文件中连接需要使用Content-->
<!--<ContentControl Grid.Row="1" Content="{Binding Body}"/>--><!--更改:使用prism的方式,降低耦合性,使用ContentRegion进行识别-->
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion"/>

MainWindowViewModel.cs文件中:

//执行不同的模块
public DelegateCommand<string> OpenCommand { get; private set; }private readonly IRegionManager regionManager;
//以下:使用prism的方式进行
public MainWindowViewModel(IRegionManager regionManager)
{//regionManager主要用于管理模块OpenCommand = new DelegateCommand<string>(Open);this.regionManager = regionManager;}
private void  Open(string obj) 
{//regionManager.Regions["ContentRegion"].RequestNavigate("Page1"); //依赖注入的形式(在App中进行同步修改)识别Page1regionManager.Regions["ContentRegion"].RequestNavigate(obj);
}

Open(string obj) 会根据button commmand的内容对应填入obj的值

<Button Margin="5" Content="打开模块A" Command="{Binding OpenCommand}" CommandParameter="Page1"/>
<Button Margin="5" Content="打开模块B" Command="{Binding OpenCommand}" CommandParameter="Page2"/>
<Button Margin="5" Content="打开模块C" Command="{Binding OpenCommand}" CommandParameter="Page3"/>

在App.xaml.cs中依赖注入使ViewA能被识别
在这里插入图片描述
以上就完成了,使用prism插件,使用依赖注入,完成点击按钮切换页面的功能。
总结:首先通过IRegionManager接口获取当全局定义的可用区域,然后往这个区域动态的设置内容,设置方式:依赖注入

16.prism模块化介绍(3)

项目开发时往往会分多个模块进行开发,多个文件夹,本质上也是一个类库。此处讲解如何添加程序集到主程序的容器中:
以新建项目类库为例:基于整个解决方案,新建两个WPF类库项目,分别命名为:ModelA,和ModelB。
在ModelA和ModelB中添加Views文件夹,在ModelA文件夹中添加用户控件ViewA,在ModelB文件夹中添加用户控件ViewB。
程序集被识别成模块的特征:新定义一个类ModuleAprofile.cs,项目中添加prism.dryIoc包之后,使ModuleAprofile继承自IModule,并实现对应的接口方法(函数内容可为空,但是必须实现)
在这里插入图片描述
在上文此.cs文件中的RegisterTypes函数中加入其依赖注入:(ModelB中同样步骤进行添加)

public void RegisterTypes(IContainerRegistry containerRegistry)
{containerRegistry.RegisterForNavigation<ViewA>();
}

如何使之联系起来?:在主程序中加载ModuleA和ModuleB的方式有两种:一种是代码的方式,一种是配置文件的方式:

第一种:代码的方式

(此处需要注意使用插件创建的原始项目自动导入的是.net 6.0 而ModuleA和ModuleB导入的是8.0 需要版本变为一致,否则会报错。《项目->属性 中可修改版本》)
在主程序中加入项目引用,ModuleA和ModuleB
然后在App.xmls.cs中增加和修改:

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{在此加入依赖注入//containerRegistry.RegisterForNavigation<Page1>(); //后面的小括号可以重命名名字,不填的话就为<>中的Page1//containerRegistry.RegisterForNavigation<Page2>();//containerRegistry.RegisterForNavigation<Page3>();
}//主程序中导入ModuleA和ModuleB,方法一:代码的模式
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{moduleCatalog.AddModule<ModuleAprofile>();moduleCatalog.AddModule<ModuleBprofile>();base.ConfigureModuleCatalog(moduleCatalog);
}

在主程序的页面MainWindow.xaml中:修改为对应的ViewA,ViewB

<StackPanel Orientation="Horizontal"><Button Margin="5" Content="打开模块A" Command="{Binding OpenCommand}" CommandParameter="ViewA"/><Button Margin="5" Content="打开模块B" Command="{Binding OpenCommand}" CommandParameter="ViewB"/><Button Margin="5" Content="打开模块C" Command="{Binding OpenCommand}" CommandParameter="Page3"/>
</StackPanel>
第二种:加载动态库dll的方式

在App.xmls.cs中增加和修改:

//第二种方式:加载动态库的方式CreateModuleCatalog
protected override IModuleCatalog CreateModuleCatalog()
{return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
}

把moduleA文件目录下bin下生成的ModelA.dll和对应的ModelB.dll放在主程序下的bin/debug目录下。

第三种:加载配置文件的方式

此不举例

17.prism导航功能(4)

之前的open有使用在区域之间进行模块的切换。此章详细讲解。
之前使用过的导航方式:
App.xaml:

 protected override void RegisterTypes(IContainerRegistry containerRegistry){在此加入依赖注入containerRegistry.RegisterForNavigation<Page1>(); //后面的小括号可以重命名名字,不填的话就为<>中的Page1//containerRegistry.RegisterForNavigation<Page2>();//containerRegistry.RegisterForNavigation<Page3>();}

ModuleA和ModuleB项目分别添加ViewModels文件夹存放对应的ViewAViewModels.cs和ViewBViewModels.cs文件
在这里插入图片描述
需要在对应的view.xaml文件中加入prism自动识别
在这里插入图片描述
也可以手动的绑定:ModuleAprofile.cs中(较为常用)
在这里插入图片描述
绑定之后,就可以在对应viewmodule中实现对应的业务代码


添加导航的参数:

在主程序的module中MainWindowViewModel.cs文件,加入导航的参数
在这里插入图片描述
在ModuleA模块中识别出来:
使ModuleA下的ModuleAViewModules.cs 使之继承自INavigationAware然后实现其对应的接口
在这里插入图片描述

//添加数据有关的基类BindableBase
public class ViewAViewModules : BindableBase,INavigationAware
{private string title;public string Title{	//要注意这里不能使用默认的private  要改为public 否则回报错get { return title; }   set { title = value; RaisePropertyChanged(); }}public bool IsNavigationTarget(NavigationContext navigationContext){//每次重新导航的时候,是否重用原来的实例return false;		//这里使用true的话下次从ModelB切换到ModelA不会进行覆盖。//throw new NotImplementedException();}public void OnNavigatedFrom(NavigationContext navigationContext){//throw new NotImplementedException();//拦截导航请求}public void OnNavigatedTo(NavigationContext navigationContext){//throw new NotImplementedException();if(navigationContext.Parameters.ContainsKey("Title")) {//用来接收viewmodule传递的参数,传递什么类型就用什么类型接收Title = navigationContext.Parameters.GetValue<string>("Title");}}
}

使用OnNavigatedFrom进行导航拦截,在进行切换时会调用此函数
方式:之前ViewAViewModules继承自INavigationAware,可以改为IConfirmNavigationRequest,实现其接口ConfirmNavigationRequest,此接口主要用于验证是否允许切换

public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
{//验证是否允许切换//throw new NotImplementedException();bool result = true;if(MessageBox.Show("确认导航?","提示",MessageBoxButton.YesNo)==MessageBoxResult.No){//如果是no 那么result = false;}continuationCallback(result);   //通过这个委托把这个结果(是否拦截导航)传进去
}

类似的导航功能还有:返回上一步:导航日志(此处省略)

18.prism对话服务(5)

也就是弹窗的功能。
在祝程序的MainWindow.xaml中,添加两个按钮进行弹窗触发。在主程序中添加窗口ViewAA.cs(以下图片上的ViewC都为ViewAA),在open函数中new此类,点击时则会有窗口出现。

在这里插入图片描述
但是特定的页面依赖于特定的实现,耦合度太高,这个问题如何去解决?-------依赖注入的方式(同上band).
将之前在主项目文件中创建的窗口ViewC.cs删掉,在ModuleA中新建一个用户控件ViewAA.cs,自定义控件的分布,提示和其他按钮。

<Grid><Grid.RowDefinitions><RowDefinition Height="auto" /><RowDefinition/><RowDefinition Height="auto" /></Grid.RowDefinitions><TextBlock Text="温馨提示" /><TextBlock Grid.Row="1" Text="hello~~~~" FontSize="80"  VerticalAlignment="Center"/><StackPanel Orientation="Horizontal" Grid.Row="2"><!--水平排列--><Button Content="取消" /><Button Content="确认" /></StackPanel>
</Grid>

在这里插入图片描述
然后注入依赖:之前注入导航是:RegisterForNavigation 现在注入对话框是:RegisterDialog
在这里插入图片描述
加入ViewAA对应的ViewAAViewModules:继承自IDialogAware,然后点击实现对应接口。

public class ViewAAViewModules : IDialogAware
{//对话框//public string Title => throw new NotImplementedException();//修改,不抛异常public string Title {  get; set; }public event Action<IDialogResult> RequestClose;public bool CanCloseDialog(){//允许被关闭return true;//throw new NotImplementedException();}public void OnDialogClosed(){//关闭窗口DialogParameters keys = new DialogParameters();keys.Add("Value", "viewAA:Dialog");RequestClose?.Invoke(new DialogResult(ButtonResult.OK, keys));//throw new NotImplementedException();}public void OnDialogOpened(IDialogParameters parameters){//接收弹窗中的参数//throw new NotImplementedException();}
}

然后在ModuleAprofile.cs注册依赖的地方,将viewAA和viewAAviewmodules进行绑定

在这里插入图片描述
对话框传递参数:主项目中MainWindowViewModel.cs中写入需要传递的参数。

//对话框
private readonly IDialogService dialogService;
public MainWindowViewModel(IDialogService dialogService)
{//regionManager主要用于管理模块OpenCommand = new DelegateCommand<string>(Open);this.dialogService = dialogService;}
private void Open(string obj)
{DialogParameters keys = new DialogParameters();keys.Add("Title", "测试弹窗");		//传递参数dialogService.ShowDialog(obj,keys,callback =>{//回调方法});
}

ViewAAViewModules中接收参数的函数OnDialogOpened修改:

public void OnDialogOpened(IDialogParameters parameters)
{//接收弹窗中的参数//throw new NotImplementedException();Title=parameters.GetValue<string>("Title");
}

点击【打开对话框A】,则显示“测试弹窗”-弹窗
在这里插入图片描述
现在把【确认/取消按钮加入对应的功能】:
ViewAAViewModules.cs写构造函数

public DelegateCommand CancelCommand {  get; set; } //取消
public DelegateCommand SaveCommand { get; set; }    //保存public ViewAAViewModules() {CancelCommand = new DelegateCommand(Cancel);SaveCommand = new DelegateCommand(Save);
}private void Save()
{//新生成方法-保存OnDialogClosed();
}private void Cancel()
{//新生成方法-取消RequestClose?.Invoke(new DialogResult(ButtonResult.No));
}

ViewAA给按钮中绑定command

 <Button Content="取消"  Command="{Binding CancelCommand}"/><Button Content="确认"  Command="{Binding SaveCommand}" />

在之前MainWindowViewModel的回调函数中进行判断

 private void Open(string obj){DialogParameters keys = new DialogParameters();keys.Add("Title", "测试弹窗");dialogService.ShowDialog(obj,keys,callback =>{//回调方法,点击之后获取点击的结果if (callback.Result == ButtonResult.OK) {//如果点击了ok那么获取传递的值string result = callback.Parameters.GetValue<string>("Value");}});}

实现点击确定按钮(OK)进行数据传递,点击取消按钮(NO)不做操作

好处:实现业务代码的简化,耦合性降低

19.prism发布订阅(6)

创建Event文件夹,创建一个新的类:MessageEvent.cs文件,消息模型。
在这里插入图片描述
使用:ViewAAViewModules.cs构造函数注入
在这里插入图片描述
例如,在ViewAA.xaml中,进行订阅:

在这里插入图片描述
进行测试:
修改ViewAAViewModules.cs
在这里插入图片描述
测试:ViewAAViewModules.cs点击取消按钮发布信号
在这里插入图片描述
实现效果:点击打开对话框A–》弹出测试弹窗 --》点击测试弹窗取消–》
弹出接收消息弹窗
在这里插入图片描述
取消订阅功能实现:点击取消,接收到消息之后取消该消息的订阅,则第二次点击取消按钮不会再弹窗。ViewAA.xaml.cs文件
在这里插入图片描述
扩展:也可以写复杂类型的对象:

namespace ModelA.Event
{public class MessageEvent:PubSubEvent<string >{//主要用来传递string类型的消息}public class TestEvent : PubSubEvent<Test>{}public class Test{public string Id {  get; set; }public string Name { get; set; }}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/50051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习 | 回归算法原理——随机梯度下降法

Hi&#xff0c;大家好&#xff0c;我是半亩花海。接着上次的多重回归继续更新《白话机器学习的数学》这本书的学习笔记&#xff0c;在此分享随机梯度下降法这一回归算法原理。本章的回归算法原理还是基于《基于广告费预测点击量》项目&#xff0c;欢迎大家交流学习&#xff01;…

uniapp中出现图片过小会与盒子偏离

结论&#xff1a;在image的父盒子中加上display: flex&#xff0c;原因不清楚 出问题的代码和图片如下&#xff1a; <template><view style" background-color: greenyellow; height: 10rpx;width: 10rpx;"><image :src"imgSrc.seatnull" …

嵌入式C++、MQTT、数据库、Grafana、机器学习( Scikit-learn):智能建筑大数据管理平台(代码示例)

项目概述 智能建筑管理系统&#xff08;Intelligent Building Management System, IBMS&#xff09;是一个集成多种技术的复杂系统&#xff0c;旨在通过智能化手段提升建筑的管理效率、节能效果和居住舒适度。该系统涉及嵌入式系统、物联网&#xff08;IoT&#xff09;、大数据…

光明乳业:以科技赋能品质,引领乳业绿色新未来

近日&#xff0c;光明乳业再次成为行业焦点&#xff0c;其在科技创新与绿色发展方面的卓越表现赢得了广泛赞誉。作为中国乳制品行业的领军企业&#xff0c;光明乳业始终坚守品质至上的原则&#xff0c;不断探索科技创新之路&#xff0c;致力于为消费者提供更高品质、更健康的乳…

vdb:虚拟数据库

将文件虚拟成数据库&#xff0c;序列化写入、反序列化读取、直接读取。

Adobe正通过数字体验改变世界

在当今这个数字化飞速发展的时代&#xff0c;Adobe公司正以其创新的技术和卓越的产品引领着创意设计领域的变革。从Adobe发布的生成式AI工具&#xff08;Adobe Firefly&#xff09;&#xff0c;到Illustrator和Photoshop的新AI功能&#xff0c;再到广受认可的Adobe国际认证&…

GLSL教程 第5章:光照和材质

目录 5.1 光照模型基础 5.2 Phong光照模型 5.3 Blinn-Phong光照模型 5.4 Cook-Torrance光照模型 5.5 Lambert光照模型 5.6 材质属性的深入讲解 小结 光照和材质是计算机图形学中至关重要的元素&#xff0c;它们共同决定了渲染图像的视觉效果。光照模型用于模拟光源与物体…

政安晨【零基础玩转各类开源AI项目】基于Ubuntu系统部署LivePortrait :通过缝合和重定向控制实现高效的肖像动画制作

目录 项目论文介绍 论文中实际开展的工作 非扩散性的肖像动画 基于扩散的肖像动画 方法论 基于Ubuntu的部署实践开始 1. 克隆代码并准备环境 2. 下载预训练权重 3. 推理 快速上手 驱动视频自动裁剪 运动模板制作 4. Gradio 界面 5. 推理速度评估 社区资源 政安…

electron安装及快速创建

electron安装及快速创建 electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 详细内容见官网&#xff1a;https://www.electronjs.org/zh/docs/latest/。 今天来记录下练习中的安装过程和hello world的创建。 创建项目文件夹&#xff0c;并执行npm 初始化命…

迅雷强制升级,漠视用户权力

用着迅雷&#xff0c;突然闪退&#xff0c;弹出升级界面。没有任何经过我的同意和操作&#xff0c;直接退出&#xff0c;强制升级。非常的蛮横和强硬。 升级完成之后&#xff0c;弹出一个提示框&#xff0c;提示框里有一个启动按钮&#xff0c;和一个加入开机自启的勾选框。意…

【Python实战】Google Chrome的离线小恐龙游戏

文章目录 Google Chrome的离线小恐龙游戏项目结构大纲 &#x1f4ca;&#x1f463;逐步编码过程 &#x1f9e9;&#x1f4a1;第一步&#xff1a;项目初始化与主程序框架第二步&#xff1a;实现T-Rex的跳跃功能第三步&#xff1a;添加障碍物和碰撞检测第四步&#xff1a;添加得分…

前端面试项目细节重难点分享(十三)

面试题提问&#xff1a;分享你最近做的这个项目&#xff0c;并讲讲该项目的重难点&#xff1f; 答&#xff1a;最近这个项目是一个二次迭代开发项目&#xff0c;迭代周期一年&#xff0c;在做这些任务需求时&#xff0c;确实有很多值得分享的印象深刻的点&#xff0c;我讲讲下面…

go语言学习文档精简版

Go语言是一门开源的编程语言&#xff0c;目的在于降低构建简单、可靠、高效软件的门槛。Go平衡了底层系统语言的能力&#xff0c;以及在现代语言中所见到的高级特性。 你好&#xff0c;Go package main // 程序组织成包import "fmt" // fmt包用于格式化输出数据// …

排序算法详解

​ &#x1f48e;所属专栏&#xff1a;数据结构与算法学习 &#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ &#x1f341;1. 插入排序 &#x1f341;1.1 直接插入排序 插入排序是一种简单直观的排序算法&#xff0c;它的原理是通过构建有序序列&#xff0c;对于未排序数…

使用 Visual Studio 2022 自带的 cl.exe 测试编译 opencv helloworld

1. 参考博客&#xff1a;https://blog.csdn.net/yangSHU21/article/details/130237669( 利用OpenCV把一幅彩色图像转换成灰度图 )( 代码用的此博客的&#xff0c;就改了下图片文件路径而已 )。 2. 编译探索步骤&#xff1a; test.cpp&#xff1a; #include <iostream>…

Golang | Leetcode Golang题解之第283题移动零

题目&#xff1a; 题解&#xff1a; func moveZeroes(nums []int) {left, right, n : 0, 0, len(nums)for right < n {if nums[right] ! 0 {nums[left], nums[right] nums[right], nums[left]left}right} }

单证不一致清关难题 | 国际贸易综合服务平台 | 箱讯科技

什么是单证一致&#xff1f; 单证一致出口方所提供的所有单据要严格符合进口方开证银行所开信用证的要求&#xff0c;或者说出口方制作和提供的所有与本项货物买卖有关的单据&#xff0c;与进口方申请开立的信用证对单据的要求完全吻合&#xff0c;没有矛盾。 添加图片注释&am…

【Stable Diffusion】(基础篇四)—— 模型

模型 本系列博客笔记主要参考B站nenly同学的视频教程&#xff0c;传送门&#xff1a;B站第一套系统的AI绘画课&#xff01;零基础学会Stable Diffusion&#xff0c;这绝对是你看过的最容易上手的AI绘画教程 | SD WebUI 保姆级攻略_哔哩哔哩_bilibili 本文主要讲解如何下载和使…

Spire.PDF for .NET【文档操作】演示:在 PDF 中添加、隐藏或删除图层

PDF 图层是一种将 PDF 文件的内容按图层排列的功能&#xff0c;允许用户在同一个 PDF 文件中选择性地将某些内容设置为可见&#xff0c;将其他内容设置为不可见。PDF 图层是分层艺术品、地图和 CAD 图纸中使用的常见元素。本文将演示如何使用Spire.PDF for .NET以编程方式在 PD…

分类常用的评价指标-二分类/多分类

二分类常用的性能度量指标 精确率、召回率、F1、TPR、FPR、AUC、PR曲线、ROC曲线、混淆矩阵 「精确率」查准率 PrecisionTP/(TPFP) 「召回率」查全率RecallTP/(TPFN) 「真正例率」即为正例被判断为正例的概率TPRTP/(TPFN) 「假正例率」即为反例被判断为正例的概率FPRFP/(TNFP)…