WPF 实现点击按钮跳转页面功能

方法1.

配置环境

首先添加prism依赖项,配置好所有文件。需要配置的有两个文件:App.xaml.cs和App.xaml

App.xaml.cs

using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;namespace PrismDemo
{/// <summary>/// Interaction logic for App.xaml/// </summary>public partial class App : PrismApplication{protected override Window CreateShell(){return Container.Resolve<MainView>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){}}
}

App.xaml

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

在MainView.xaml中添加下面两句话,引用prism并且实现自动关联上下文,即自动加载与视图关联的视图模型

xmlns:prism="http://prismlibrary.com/"

prism:ViewModelLocator.AutoWireViewModel="True"

创建两个文件:Views和ViewModels

Views 文件夹:包含所有的 XAML 文件,用于定义应用程序的用户界面。

每个 XAML 文件都对应一个界面,如 MainWindow.xaml、SettingsView.xaml 等等。

在 Views 文件夹中通常不会包含任何代码逻辑,只包含 XAML 标记。

ViewModels 文件夹:包含所有的 ViewModel 类,用于处理视图和模型之间的交互和状态管理。

每个 ViewModel 类都对应一个视图,如 MainWindowViewModel.cs、SettingsViewModel.cs 等等。

在 ViewModels 文件夹中通常不会包含任何与界面相关的代码,只包含处理视图和模型之间交互的业务逻辑。

在 MVVM 模式中,View 和 ViewModel 之间的通信通常使用数据绑定来实现。通过将 ViewModel 的属性和命令与 View 的元素绑定,可以将 ViewModel 中的数据和行为更新到 View 中。例如,可以将 ViewModel 中的一个属性绑定到 TextBlock 的 Text 属性,将一个命令绑定到 Button 的 Command 属性。这种数据绑定机制使得 View 和 ViewModel 之间的交互变得非常方便和灵活。

MainView.xaml

此段代码是页面展示部分,它定义了两行。第一行包含三个按钮,第二行包含一个内容控件。

每个按钮绑定了一个OpenCommand命令,并传递了一个字符串参数,用于打开不同的窗口。

内容控件 ContentControl 的内容被绑定到了一个 Body 属性,用于显示窗口中的主要内容。

<Windowx:Class="PrismDemo.Views.MainView"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:local="clr-namespace:PrismDemo"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:prism="http://prismlibrary.com/"Title="MainWindow"Width="800"Height="450"prism:ViewModelLocator.AutoWireViewModel="True"mc:Ignorable="d"><Grid><Grid.RowDefinitions><RowDefinition Height="auto" /><RowDefinition /></Grid.RowDefinitions><StackPanel Orientation="Horizontal"><ButtonMargin="5"Command="{Binding OpenCommand}"CommandParameter="ViewA"Content="打开模块A" /><ButtonMargin="5"Command="{Binding OpenCommand}"CommandParameter="ViewB"Content="打开模块B" /><ButtonMargin="5"Command="{Binding OpenCommand}"CommandParameter="ViewC"Content="打开模块C" /></StackPanel><ContentControl Grid.Row="1" Content="{Binding Body}" /></Grid>
</Window>

ViewX.xaml

Views文件夹中一共有四个.xaml文件,除了主窗口的MainView.xaml外,其他三个分别是ViewA.xaml、ViewB.xaml 和 ViewC.xaml,分别对应于点击主窗口中按钮后的转换窗口,其中只有一行文本内容。

<TextBlock FontSize="80" Text="ViewX" /> (X=A, B, C)

MainViewModel.cs

MainViewModel.cs 继承自 Prism 库中的 BindableBase 类,实现了窗口布局中用到的命令和属性。

DelegateCommand<string> OpenCommand 是一个命令属性,用于绑定窗口中的三个按钮。

这个命令属性在构造函数中被初始化为一个 DelegateCommand<string> 对象,并指定了一个参数类型为字符串的委托方法 Open。这个委托方法用于执行不同的模块打开操作。

Body 属性是一个对象属性,用于绑定窗口布局中的内容控件。它的 get 方法返回 body 字段的值,而 set 方法则将传入的值设置给 body 字段,并通过 RaisePropertyChanged() 方法通知视图更新。

Open(string obj) 方法是 OpenCommand 委托方法的实现,它接受一个字符串参数 obj,用于判断要打开哪个模块。根据参数值的不同,通过 Body 属性设置不同的视图。例如,当参数值为 "ViewA" 时,设置 Body 为一个 ViewA 的实例,从而实现了打开界面 A 的功能。

using Prism.Commands;
using Prism.Mvvm;
using PrismDemo.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PrismDemo.ViewModels
{internal class MainViewModel:BindableBase{//负责执行不同的模块public DelegateCommand<string> OpenCommand { get; private set; }public MainViewModel(){OpenCommand = new DelegateCommand<string>(Open);}private object body;public object Body{get { return body; }set { body = value; RaisePropertyChanged(); }}private void Open(string obj){switch (obj){           case "ViewA": Body = new ViewA(); break;case "ViewB": Body = new ViewB(); break;case "ViewC": Body = new ViewC(); break;}}}
}

方法2. 使用依赖注入动态设置内容

MainView.xaml

修改内容:

<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion" />

prism:RegionManager.RegionName="ContentRegion" 属性是使用 Prism 库中的区域管理器(Region Manager)功能来定义了一个名为 "ContentRegion" 的区域。

这个区域用于管理将要显示在 <ContentControl> 控件中的内容。

在这个区域中可以动态地加载和卸载不同的视图,从而实现复杂的界面交互和布局。

在 Prism 应用程序中,我们通常使用区域管理器来动态加载和卸载不同的视图,以实现应用程序的模块化和松耦合。例如,在一个具有多个区域的应用程序中,每个区域可以单独管理自己的视图,使得应用程序的不同模块之间可以相互独立地开发、测试和维护。

下面是MainView.xaml的完整代码:

<Windowx:Class="PrismDemo.Views.MainView"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:local="clr-namespace:PrismDemo"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:prism="http://prismlibrary.com/"Title="MainWindow"Width="800"Height="450"prism:ViewModelLocator.AutoWireViewModel="True"mc:Ignorable="d"><Grid><Grid.RowDefinitions><RowDefinition Height="auto" /><RowDefinition /></Grid.RowDefinitions><StackPanel Orientation="Horizontal"><ButtonMargin="5"Command="{Binding OpenCommand}"CommandParameter="ViewA"Content="打开模块A" /><ButtonMargin="5"Command="{Binding OpenCommand}"CommandParameter="ViewB"Content="打开模块B" /><ButtonMargin="5"Command="{Binding OpenCommand}"CommandParameter="ViewC"Content="打开模块C" /></StackPanel><ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion" /></Grid>
</Window>

MainViewModel.cs

OpenCommand 属性与上面意义相同,用于在用户点击打开按钮时执行 Open 方法。

Open 方法根据传入的参数 obj 来决定要打开哪个模块,并通过区域管理器(IRegionManager)来请求加载指定模块的视图。

在构造函数中接受了一个 IRegionManager 类型的参数,用于从依赖注入容器中获取区域管理器的实例。这样,我们就可以通过注入区域管理器来使用 Prism 库中提供的区域管理器功能,从而实现对区域中的视图进行动态加载和卸载等操作。

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using PrismDemo.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PrismDemo.ViewModels
{internal class MainViewModel:BindableBase{//负责执行不同的模块public DelegateCommand<string> OpenCommand { get; private set; }private readonly IRegionManager regionManager;//IRegionManager: 主要负责管理定义的所有可用区域public MainViewModel(IRegionManager regionManager){OpenCommand = new DelegateCommand<string>(Open);this.regionManager = regionManager;}private void Open(string obj){//在这个区域通过依赖注入动态设置内容,regionManager.Regions["ContentRegion"].RequestNavigate(obj);}}
}

App.xaml.cs

修改内容:

protected override void RegisterTypes(IContainerRegistry containerRegistry)

{

containerRegistry.RegisterForNavigation<ViewA>();

containerRegistry.RegisterForNavigation<ViewB>();

containerRegistry.RegisterForNavigation<ViewC>();

}

在使用 Prism 进行开发时,通常需要在应用程序启动时注册应用程序使用的服务和视图模型等对象,这个过程就叫做注册。

在 Prism 中,使用 IContainerRegistry 接口来完成依赖注入的注册过程,

RegisterForNavigation 方法是用来注册导航对象(视图)的方法。

该方法通过传入导航目标对象类型作为泛型参数,告诉 Prism 在使用该导航时应该使用哪个视图对象。因此,调用该方法将允许我们在 Prism 中使用导航和在容器中注入视图。

具体来说,RegisterForNavigation<ViewA>() 会将类型 ViewA 注册为一个可导航的视图对象,当需要导航到 ViewA 时,Prism 会自动创建该视图对象并将其添加到对应的区域中,而无需手动实例化该对象。

通常,在应用程序启动时,我们会在 App.xaml.cs 中重写 ConfigureContainerRegisterTypes 方法,从而将应用程序中需要的服务和对象注册到容器中,以便在整个应用程序中使用。

using Prism.DryIoc;
using Prism.Ioc;
using PrismDemo.Views;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace PrismDemo
{public partial class App : PrismApplication{protected override Window CreateShell(){return Container.Resolve<MainView>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterForNavigation<ViewA>();containerRegistry.RegisterForNavigation<ViewB>();containerRegistry.RegisterForNavigation<ViewC>();      }}
}

Prism的模块化

创建多个项目,将项目输出类型设为类库。创建页面并创建类对此界面进行注册。

创建内容如下:

其中的ViewA、ViewB和MainViewModel.cs中的内容和方法2中相同。

ModuleAProfile.cs

这段代码定义了一个名为 ModuleAProfile 的类,实现了 Prism 库中的 IModule 接口。

在 Prism 中,模块是一种组织和管理功能的机制,通常使用模块将应用程序分解为可重用和独立的部分,从而简化开发和维护。

IModule 接口要求实现两个方法:RegisterTypesOnInitialized

在这个例子中,ModuleAProfile 类只实现了 RegisterTypes 方法。在该方法中,通过调用 containerRegistry.RegisterForNavigation<ViewA>() 方法来将 ViewA 类型注册为可导航的视图。在这里,RegisterForNavigation 方法是 Prism 库提供的一种方便的方法,用于在应用程序中注册可导航的视图,使其能够通过 URI 进行导航。

using ModuleA.Views;
using Prism.Ioc;
using Prism.Modularity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModuleA
{public class ModuleAProfile : IModule{public void OnInitialized(IContainerProvider containerProvider){}public void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterForNavigation<ViewA>();}}
}

ModuleBProfile.cs

using ModuleB.Views;
using Prism.Ioc;
using Prism.Modularity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModuleB
{public class ModuleBProfile : IModule{public void OnInitialized(IContainerProvider containerProvider){}public void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterForNavigation<ViewB>();}}
}

App.xaml.cs

创建完上面两个ModuleAProfile和ModuleB文件之后,要在主页面中加入依赖项,而此文件的主要目的是使用ConfigureModuleCatalog()方法来配置应用程序的模块目录。

ConfigureModuleCatalog()方法里添加了两个模块 ModuleAProfileModuleBProfile

因此,这个应用程序使用 DryIoc 作为 IoC 容器,创建了一个主窗口,并配置了两个模块。这些模块将在应用程序启动时被加载。

using ModuleA;
using ModuleB;
using Prism.DryIoc;
using Prism.Ioc;
using Prism.Modularity;
using PrismDemo.Views;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace PrismDemo
{public partial class App : PrismApplication{protected override Window CreateShell(){return Container.Resolve<MainView>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){ }protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog){moduleCatalog.AddModule<ModuleAProfile>();moduleCatalog.AddModule<ModuleBProfile>();base.ConfigureModuleCatalog(moduleCatalog);}}
}

引用ModuleAProfile 和 ModuleBProfile的第二种方式

  1. 不添加依赖项
  2. 修改App.xaml.cs
  3. 在主程序文件的指定位置创建文件Modules,将ModuleA和ModuleB的dll文件移动到此文件中。

此方法比上面引用方法耦合性更低,不需要指定调用哪个模块,ModuleA、ModuleB和主程序直接无直接联系。

App.xaml.cs

using Prism.DryIoc;
using Prism.Ioc;
using Prism.Modularity;
using PrismDemo.Views;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;namespace PrismDemo
{/// <summary>/// Interaction logic for App.xaml/// </summary>public partial class App : PrismApplication{protected override Window CreateShell(){return Container.Resolve<MainView>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){}protected override IModuleCatalog CreateModuleCatalog(){return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };}}
}

文件创建位置

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

正点原子嵌入式linux驱动开发——STM32MP1启动详解

STM32单片机是直接将程序下载到内部 Flash中&#xff0c;上电以后直接运行内部 Flash中的程序。 STM32MP157内部没有供用户使用的 Flash&#xff0c;系统都是存放在外部 Flash里面的&#xff0c;比如 EMMC、NAND等&#xff0c;因此 STM32MP157上电以后需要从外部 Flash加载程序…

Linux高性能服务器编程 学习笔记 第九章 IO复用

IO复用使程序能同时监听多个文件描述符&#xff0c;这可以提高程序的性能&#xff0c;通常网络程序在以下情况需要使用IO复用&#xff1a; 1.客户端进程需要同时处理多个socket。 2.客户端进程需要同时处理用户输入和网络连接。 3.TCP服务器要同时处理监听socket和连接socket…

配置OSPF路由

OSPF路由 1.OSPF路由 1.1 OSPF简介 OSPF(Open Shortest Path First&#xff0c;开放式最短路径优先&#xff09;路由协议是另一个比较常用的路由协议之一&#xff0c;它通过路由器之间通告网络接口的状态&#xff0c;使用最短路径算法建立路由表。在生成路由表时&#xff0c;…

【通意千问】大模型GitHub开源工程学习笔记(2)--使用Qwen进行推理的示例代码解析,及transformers的库使用

使用Transformers来使用模型 如希望使用Qwen-chat进行推理,所需要写的只是如下所示的数行代码。请确保你使用的是最新代码,并指定正确的模型名称和路径,如Qwen/Qwen-7B-Chat和Qwen/Qwen-14B-Chat 这里给出了一段代码 from transformers import AutoModelForCausalLM, Aut…

机器学习笔记 - 基于强化学习的贪吃蛇玩游戏

一、关于深度强化学习 如果不了解深度强化学习的一般流程的可以考虑看一下下面的链接。因为这里的示例因为在PyTorch 之上实现深度强化学习算法。 机器学习笔记 - Deep Q-Learning算法概览深度Q学习是一种强化学习算法,它使用深度神经网络来逼近Q函数,用于确定在给定状态下采…

ROS2 中的轻量级、自动化、受控回放

一、说明 这篇文章描述了一种在 ROS2 中实现受控重播器的轻量级方法。用以测试中将现象重新播放一遍&#xff0c;以实现调参或故障定位的目的。所有源代码都可以在这里找到。该帖子也可在此处获得。 二、问题&#xff1a;不同步重播 任何曾经认真开发过 ROS2 的人都会知道这个问…

springboot和vue:八、vue快速入门

vue快速入门 新建一个html文件 导入 vue.js 的 script 脚本文件 <script src"https://unpkg.com/vuenext"></script>在页面中声明一个将要被 vue 所控制的 DOM 区域&#xff0c;既MVVM中的View <div id"app">{{ message }} </div…

uboot启动流程涉及reset汇编函数

一. uboot启动流程中函数 之前了解了uboot链接脚本文件 u-boot.lds。 从 u-boot.lds 中我们已经知道了入口点是 arch/arm/lib/vectors.S 文件中的 _start。 本文了解 一下&#xff0c;uboot启动过程中涉及的 reset 函数。本文继上一篇文章学习&#xff0c;地址如下&#xff…

统计模型----决策树

决策树 &#xff08;1&#xff09;决策树是一种基本分类与回归方法。它的关键在于如何构建这样一棵树。决策树的建立过程中&#xff0c;使用基尼系数来评估节点的纯度和划分的效果。基尼系数是用来度量一个数据集的不确定性的指标&#xff0c;其数值越小表示数据集的纯度越高。…

揭秘:机构招生电子传单制作的五个黄金法则

机构招生微传单制作一直都是让很多人在意的事情。一款好的微传单不仅可以吸引更多的学生&#xff0c;还可以省去很多招生工作的时间和精力。但是&#xff0c;很多人却不知道如何制作一款精美的微传单。下面就让我们来学习一下如何制作一款机构招生的微传单吧。 首先&#xff0c…

Egg 封装接口返回信息

中间件封装 代码 const msgArr {"200":成功,"401":token失效 } module.exports (option, app) > {return async function(ctx, next) {try{//成功是返回的信息ctx.emit(code,data,msg)>{console.log(1111,code,data,msg)ctx.body {code,data:dat…

springboot 简单配置mongodb多数据源

准备工作&#xff1a; 本地mongodb一个创建两个数据库 student 和 student-two 所需jar包&#xff1a; # springboot基于的版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>&l…

C++之std::atomic解决多线程7个问题(二百四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

竞赛选题 多目标跟踪算法 实时检测 - opencv 深度学习 机器视觉

文章目录 0 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习多目标跟踪 …

uniapp使用scroll-into-view实现锚点定位和滚动监听功能【楼层效果 / 侧边导航联动效果】

大佬网址&#xff1a; https://blog.csdn.net/weixin_47136265/article/details/132303570 效果 代码 <template><!-- 这里面有2个bug&#xff0c;已经解决&#xff0c;需要知道的地方1.methods里的scrollEvt(e)方法里面的 this.tabIndex index ! -1 ? index :…

MySQL - DML数据增删改

功能介绍&#xff1a; DML&#xff08;Data Manipulation Language&#xff09;数据操作语言&#xff0c;用来对数据库中表的数据记录进 行增、删、改操作。 添加数据&#xff08;INSERT&#xff09; 基本语法&#xff1a;insert into 表名(字段列表) values (值列表); …

el-collapse 嵌套中 el-checkbox作为标题,选中复选框与el-tree联动

<el-drawertitle"应用授权":visible.sync"menuDrawer"><el-collapse accordion style"padding: 15px"><el-collapse-item v-for"item in platList"><template slot"title"><el-checkbox v-model…

Mysql各种锁

一.不同存储引擎支持的锁机制 Mysql数据库有多种数据存储引擎&#xff0c;Mysql中不同的存储引擎支持不同的锁机制 MyISAM和MEMORY存储引擎采用的表级锁 InnoDB存储引擎支持行级锁&#xff0c;也支持表级锁&#xff0c;默认情况下采用行级锁 二.锁类型的划分 按照数据操作…

postgresql-管理数据表

postgresql-管理数据表 创建表数据类型字段约束表级约束模式搜索路径 修改表添加字段删除字段添加约束删除约束修改字段默认值修改字段数据类型重命名字段重命名表 删除表 创建表 在 PostgreSQL 中&#xff0c;使用 CREATE TABLE 语句创建一个新表&#xff1a; CREATE TABLE …

深度学习笔记_1、定义神经网络

1、使用了PyTorch的nn.Module类来定义神经网络模型;使用nn.Linear来创建全连接层。(CPU) import torch.nn as nn import torch.nn.functional as F from torchsummary import summary# 定义神经网络模型 class Net(nn.Module):def __init__(self):super(Net, self).__init__()…