WPF开发03-Prism学习笔记

news/2025/1/23 14:49:13/文章来源:https://www.cnblogs.com/hezexi/p/18510333

@

目录
  • 1.Prism的一些特点
  • 2.使用步骤
  • 3.什么是Region
  • 4.BindableBase
  • 5.模块Module
    • 1.简介
    • 2. 创建模块Module
    • 3.视图注入:
  • 6.MVVM
  • 7.DelegateCommand命令、CompositeCommand复合命令
  • 8.事件聚合器IEventAggregator
    • 1.普通的发布和订阅事件
    • 2.事件过滤器
  • 9.导航Navigation
  • 10.对话服务Dialog
    • 1.简介
    • 2.创建一个对话框

Prism是WPF中一个比较知名的框架,简单记录下学习Prism框架过程中的一些知识点。

在这里插入图片描述

1.Prism的一些特点

在Prism当中,你可以遵循默认约定,即可自动将View/ViewModel建立DataContext的关系,同时默认支持多种容器依赖注入,其强大的模块化、导航功能能够将应用变得更加灵活自如。 Prism支持的一些功能:

  • 通知BindableBase;
  • 命令DelegateCommand;
  • 聚合器IEventAggregator;
  • 模块化;
  • 容器;
  • 依赖注入;
  • 导航;
  • 对话;

2.使用步骤

可在vs2022中快速创建Prism模板工程,

在这里插入图片描述

3.什么是Region

  1. Region作为Prism当中模块化的核心功能,其主要目的是弱化了模块与模块之间的耦合关系。在普遍的应用程序开发中,界面上的元素及内容往往被固定;而在Prism中,可以不再为其固定内容,从而有了区域的概念,现在将页面每个部分定于一个唯一区域(Region),那么在运行时,我们可以对每个区域动态设置内容。

在这里插入图片描述

  1. 使用区域管理器RegionManager来定义Region。

    定义Region的方式有两种,一种是在XAML界面指定,另一种是在代码中指定:
  • XAML指定:RegionManager.RegionName;
  • 代码中指定:RegionManager.SetRegionName;

    RegionManager除了定义区域,还有以下功能:
  • 维护区域集合;
  • 提供对区域的访问;
  • 合成视图;
  • 区域导航;
  • 定义区域;
  1. 区域适配器RegionAdapter。实际上,Prism内置了几个区域适配器,所以我们在ContentControl当中定义区域,实际可以在任何元素上定义区域,如果定义的范围不在官方提供的默认适配器当中,则会引发异常。
    Prism内置的几个区域适配器:
  • ContentControlRegionAdapter
  • ItemsControlRegionAdapter
  • SelectorRegionAdapter
  • ComboBox
  • ListBox
  • Ribbon
  • TabControl
  • ContentControl

    例如,StackPanel并不存在于官方默认自带的区域适配器,当我们强行用StackPanel作为区域适配器的时候,会报以下错误:

在这里插入图片描述
在这里插入图片描述

当然,我们也可以自定义一个区域适配器:比如,要给StackPanel新建一个适配器:需要新建一个名称为StackPanelRegionAdapters的类,并实现如下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Prism.Regions;namespace PrismApp.CustomRegionAdapters
{public class StackPanelRegionAdapters : RegionAdapterBase<StackPanel>{public StackPanelRegionAdapters(IRegionBehaviorFactory regionBehaviorFactory) : base(regionBehaviorFactory){}/// <summary>/// 当在StackPanel中动态添加一些内容或子控件时,需要重写该Adapt函数/// </summary>/// <param name="region"></param>/// <param name="regionTarget"></param>protected override void Adapt(IRegion region, StackPanel regionTarget){//当给StackPanel中动态添加一些内容或子控件时,CollectionChanged事件就会被触发region.Views.CollectionChanged += (s, e) =>{if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)//如果e.Action检测到是向StackPanel中添加内容或控件而不是移除{foreach(FrameworkElement item in e.NewItems)//遍历所有新添加的内容或子控件,然后添加子元素进regionTarget;{regionTarget.Children.Add(item);}}};}protected override IRegion CreateRegion(){return new Region();}}
}

然后在App.xaml.cs中,通过重写ConfigureRegionAdapterMappings方法初始化该区域适配器:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Prism.DryIoc;
using Prism.Ioc;
using Prism.Regions;
using PrismApp.CustomRegionAdapters;
using PrismApp.Views;namespace PrismApp
{/// <summary>/// App.xaml 的交互逻辑/// </summary>public partial class App : PrismApplication{/// <summary>/// 用来创建主窗体/// </summary>/// <returns></returns>protected override Window CreateShell(){return Container.Resolve<MainWindowView>();}/// <summary>/// 可以用来给容器中注册对象/// </summary>/// <param name="containerRegistry"></param>protected override void RegisterTypes(IContainerRegistry containerRegistry){}/// <summary>/// 这段代码的作用:在Prism初始化的时候,把区域适配器添加进去,以便能加载自定义的区域适配器/// </summary>/// <param name="regionAdapterMappings"></param>protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings){base.ConfigureRegionAdapterMappings(regionAdapterMappings);regionAdapterMappings.RegisterMapping(typeof(StackPanel), Container.Resolve<StackPanelRegionAdapters>());}}
}

此时再次运行程序,StackPanel区域适配器就可以用了,程序不再报错:

在这里插入图片描述

4.BindableBase

BindableBase抽象类实现了INotifyPropertyChanged接口,主要作用当绑定到界面的数据发生改变的时候可以通知界面进行更新。

在这里插入图片描述

   private string _message;public string Message{get { return _message; }set { SetProperty(ref _message, value); }//这一行也可以写为 set { _message = value;RaisePropertyChanged(); }}

5.模块Module

1.简介

本质上来说,对于一个应用程序而言,特定功能的所有View、Logic、Service等都可以独立存在,那么意味着每个独立的功能我们都可以称之为模块。

2. 创建模块Module

创建Module实际上是将模块独立于类库存在,主程序通过加载类库添加模块,以下步骤:

  1. 创建Module: 模块实现IModule接口 ;

  2. 主程序配置模块目录, 配置方式:
    (代码方式)Code;
    (配置文件)App.config;
    (磁盘目录)Disk/Directory;
    (XAML定义)XAML;
    (自定义)Custom;

3.视图注入:

应用程序模块化后,每个子模块中的视图可以独立的进行依赖注入,再使用IRegionManager来实现页面导航。 步骤:

  • 利用Region进行导航功能;
  • 使用Module将应用程序模块化;
  • 将独立模块的视图、服务使用注入到容器当中;

如下,注册一个模块的流程:

  1. 右键单击解决方案,添加一个新项目

在这里插入图片描述

  1. 添加一个Prism Module项目

在这里插入图片描述

  1. 点击创建

在这里插入图片描述

  1. 向项目中添加该Module的引用

在这里插入图片描述

  1. 在该ModuleAModule.cs文件中实现OnInitialized方法:
public void OnInitialized(IContainerProvider containerProvider){var regionManager = containerProvider.Resolve<RegionManager>();regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));}

如图:

在这里插入图片描述

  1. 在项目的APP.xaml.cs代码中实现ConfigureModuleCatalog方法:
 protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog){moduleCatalog.AddModule<ModuleA.ModuleAModule>();}

如图:

在这里插入图片描述

此时,点击运行,ModuleA就会成功被加载

在这里插入图片描述

6.MVVM

  1. Prism中的MVVM:
    在这里插入图片描述
    如上图,我们建立了这样两个文件夹,那么MainWindow.xaml如何和MainWindowViewModel.cs建立起联系呢?只需要在MainWindow.xaml中加入这样一行代码来实现自动建立View和ViewModel之间的联系(但是View和ViewModel两个文件的命名要符合规范):
prism:ViewModelLocator.AutoWireViewModel="True"

如图:

在这里插入图片描述

7.DelegateCommand命令、CompositeCommand复合命令

  1. DelegateCommand命令的使用

在这里插入图片描述
在这里插入图片描述

  1. CompositeCommand复合命令的使用
<Grid><StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center"><Button Command="{Binding OpenAllCommand}" Width="150" Height="50"/><TextBlock Text="{Binding Message}" HorizontalAlignment="Center" VerticalAlignment="Center" /></StackPanel>    </Grid>
public class ViewAViewModel : BindableBase{private string _message;public string Message{get { return _message; }set { SetProperty(ref _message, value); }//此行也可以写为set { _message = value;RaisePropertyChanged(); }}public DelegateCommand btnCommand1 { get; set; }public DelegateCommand btnCommand2 { get; set; }public CompositeCommand OpenAllCommand { get; set; }//复合命令public ViewAViewModel(){Message = "View A from your Prism Module";btnCommand1 = new DelegateCommand(() =>{Message += "我是btnCommand1";});btnCommand2 = new DelegateCommand(() =>{Message += "我是btnCommand2";});OpenAllCommand = new CompositeCommand();//实例化复合命令类型的对象OpenAllCommand.RegisterCommand(btnCommand1);//把子命令btnCommand1注册到复合命令OpenAllCommand上去OpenAllCommand.RegisterCommand(btnCommand2);//把子命令btnCommand2注册到复合命令OpenAllCommand上去}}

运行结果:

在这里插入图片描述

8.事件聚合器IEventAggregator

IEventAggregator的作用:

  • 松耦合基于事件通讯;
  • 多个发布者和订阅者;
  • 微弱的事件;
  • 过滤事件;
  • 传递参数;
  • 取消订阅;

该功能主要作用是:事件聚合器负责接收订阅以及发布消息。订阅者可以接收到发布者发送的内容,例如:AViewModel订阅了一个消息接收的事件,然后BViewModel当中指定该事件推送消息,此时AViewModel接受BViewModel推送的内容。

1.普通的发布和订阅事件

点击“发布”按钮,再点击“订阅”按钮,再点击“发布按钮”,下边的文本框中就会出现“Hello”。 效果如下:

在这里插入图片描述

步骤:

  1. 先定义两个Button,一个用来发布事件,一个用来订阅事件,如图:

在这里插入图片描述

  1. 在后台ViewModel中实现如下6个步骤:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;namespace ModuleA.ViewModels
{public class MessageEvent1 : PubSubEvent<string> //1.实现一个类MessageEvent1(这个类的名字可以自定义),该类必须继承自泛型类PubSubEvent<>{ }public class ViewAViewModel : BindableBase{private readonly IEventAggregator eventAggregator;//2.声明一个事件聚合器private string _message;public string Message{get { return _message; }set { SetProperty(ref _message, value); }//此行也可以写为set { _message = value;RaisePropertyChanged(); }}public DelegateCommand OpenCommand { get; set; }public DelegateCommand SendCommand { get; set; }public void OnMessageReceived(string message)//4.定义一个接收订阅事件后执行的方法{Message += message;}public ViewAViewModel(IEventAggregator eventAggregator){this.eventAggregator = eventAggregator;//3.指定事件聚合器Message = "View A from your Prism Module";OpenCommand = new DelegateCommand(() =>{eventAggregator.GetEvent<MessageEvent1>().Subscribe(OnMessageReceived);//6.订阅一个事件,OnMessageReceived是订阅事件之后执行的方法});SendCommand = new DelegateCommand(() =>{eventAggregator.GetEvent<MessageEvent1>().Publish("Hello!");//5.发布一个事件,Publish后跟的是要发布的信息});}}
}

如图:

在这里插入图片描述

2.事件过滤器

///事件过滤器public virtual SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate<TPayload> filter)///关于Subscribe的四个参数:///1.actions:发布事件时执行的委托///2.ThreadOption枚举:指定在哪个线程上接收委托回调///3.keepSubscriberReferenceAlive布尔:如果为true,则Prism.Event.PubSubEvent保留对订阅者的引用因此它不会收集垃圾///4.filter:进行筛选以评估订阅者是否应该接收事件

代码举例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;namespace ModuleA.ViewModels
{public class MessageEvent1 : PubSubEvent<string> //1.实现一个类MessageEvent1(这个类的名字可以自定义),该类必须继承自泛型类PubSubEvent<>{ }public class ViewAViewModel : BindableBase{private readonly IEventAggregator eventAggregator;//2.声明一个事件聚合器private string _message;public string Message{get { return _message; }set { SetProperty(ref _message, value); }//此行也可以写为set { _message = value;RaisePropertyChanged(); }}public DelegateCommand OpenCommand { get; set; }public DelegateCommand SendCommand { get; set; }public void OnMessageReceived(string message)//4.定义一个接收订阅事件后执行的方法{Message += message;}public ViewAViewModel(IEventAggregator eventAggregator){this.eventAggregator = eventAggregator;//3.指定事件聚合器Message = "View A from your Prism Module";OpenCommand = new DelegateCommand(() =>{///事件过滤器public virtual SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate<TPayload> filter)///关于Subscribe的四个参数:///1.actions:发布事件时执行的委托///2.ThreadOption枚举:指定在哪个线程上接收委托回调///3.keepSubscriberReferenceAlive布尔:如果为true,则Prism.Event.PubSubEvent保留对订阅者的引用因此它不会收集垃圾///4.filter:进行筛选以评估订阅者是否应该接收事件eventAggregator.GetEvent<MessageEvent1>().Subscribe(OnMessageReceived, ThreadOption.PublisherThread, false, msg => {if(msg.Equals("Hello"))///当接收到发布的字符串为Hello时,就同意接收;如果不是Hello就拒绝接收{return true;}else{return false;}});//6.订阅一个事件,OnMessageReceived是订阅事件之后执行的方法});SendCommand = new DelegateCommand(() =>{eventAggregator.GetEvent<MessageEvent1>().Publish("Hello!");//5.发布一个事件,Publish后跟的是要发布的信息});}}
}

其他地方代码和上面“普通的发布和订阅事件”一样,效果如下: 点击“发布”按钮,然后点击“订阅”按钮,再点击“发布”按钮,没有显示消息

在这里插入图片描述

  1. 为注册的消息取消订阅Unsubscribe:
 eventAggregator.GetEvent<MessageEvent1>().Unsubscribe(OnMessageReceived);//5取消一个事件,OnMessageReceived是一个方法名

9.导航Navigation

  1. 参考博客
  2. 先看一个效果(知识点都写在了代码注释里):主界面中,点击"打开A"按钮就会在主界面下方区域显示A窗口同时该命令还会给窗口A传递一个值为Hello的参数,点击"打开B"按钮就会在主界面下方区域显示B窗口;
    在这里插入图片描述
    工程目录:
    在这里插入图片描述
    MainWindow.xaml(MainWindow.xaml.cs里啥都没有):
    在这里插入图片描述

ViewA.xaml(ViewA.xaml.cs里啥都没有):

在这里插入图片描述

ViewB.xaml(ViewB.xaml.cs里啥都没有):

在这里插入图片描述

App.xaml:

在这里插入图片描述

App.xaml.cs:

using System.Windows;
using BlankApp1.Views;
using Prism.Ioc;
using Prism.Modularity;namespace BlankApp1
{/// <summary>/// Interaction logic for App.xaml/// </summary>public partial class App{protected override Window CreateShell(){return Container.Resolve<MainWindow>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterForNavigation<ViewA>("PageA");//将ViewA注册为导航页面,并给ViewA起一个别名为PageA;containerRegistry.RegisterForNavigation<ViewB>();////将ViewB注册为导航页面}//protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)//{//    moduleCatalog.AddModule<ModuleA.ModuleAModule>();//}}
}

ViewAViewModel.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Mvvm;
using Prism.Regions;namespace BlankApp1.ViewModels
{public class ViewAViewModel:BindableBase,INavigationAware{private string _title;public string Title{get { return _title; }set { _title = value;RaisePropertyChanged(); }}/// <summary>/// 判断该ViewAViewModel是否已经实例化,如果返回true则会创建一个新的实例/// </summary>/// <param name="navigationContext"></param>/// <returns></returns>public bool IsNavigationTarget(NavigationContext navigationContext){return true;}/// <summary>/// 导航离开当前页时触发/// </summary>/// <param name="navigationContext"></param>public void OnNavigatedFrom(NavigationContext navigationContext){}/// <summary>/// 导航完成前,接收用户传递的参数以及是否允许导航等控制/// </summary>/// <param name="navigationContext"></param>public void OnNavigatedTo(NavigationContext navigationContext){Title= navigationContext.Parameters.GetValue<string>("Value");//拿到其他页面传递给此页面的参数Value,该Value被指定为String类型}}
}

MainWindowViewModel.cs:

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;namespace BlankApp1.ViewModels
{public class MainWindowViewModel : BindableBase{private string _title = "Prism Application";public string Title{get { return _title; }set { SetProperty(ref _title, value); }}private readonly IRegionManager regionManager;public DelegateCommand OpenACommand { get; set; }public DelegateCommand OpenBCommand { get; set; }public DelegateCommand GoBackCommand { get; set; }public DelegateCommand GoForwordCommand { get; set; }public MainWindowViewModel(IRegionManager regionManager){OpenACommand = new DelegateCommand(OpenA);OpenBCommand = new DelegateCommand(OpenB);GoForwordCommand = new DelegateCommand(GoForward);GoBackCommand = new DelegateCommand(GoBack);this.regionManager = regionManager;}public void GoBack(){}public void GoForward(){}public void OpenA(){//NavigationParameters parm=new NavigationParameters();//parm.Add("Value", "Hello");//传递一个参数,名称为Value,Value的值为Hello/////导航到指定的区域管理器//regionManager.RequestNavigate("ContentRegion", "PageA",parm);//第1个参数是要在哪个区域显示,第2个参数是要显示的页面,第3个是要给参数2要显示的页面传递的参数//注:上面那3行的作用和下面这一行一样regionManager.RequestNavigate("ContentRegion", $"PageA?Value=Hello");//第1个参数是要在哪个区域显示,第2个参数$"PageA?Value=Hello"的作用是:要显示的页面为PageA,传递的一个Value参数值为Hello}public void OpenB(){///导航到指定的区域管理器regionManager.RequestNavigate("ContentRegion", "ViewB");//第1个参数是要在哪个区域显示,第2个参数是要显示的页面}}
}
  1. 导航,通过区域导航日志IRegionNavigationJournal来实现上一页下一页功能:
    代码较1中,只有MainWindowViewModel.cs发生了改变,如下:
    效果:
    在这里插入图片描述

MainWindowViewModel.cs:

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;namespace BlankApp1.ViewModels
{public class MainWindowViewModel : BindableBase{private string _title = "Prism Application";public string Title{get { return _title; }set { SetProperty(ref _title, value); }}private readonly IRegionManager regionManager;IRegionNavigationJournal journal;//区域导航日志public DelegateCommand OpenACommand { get; set; }public DelegateCommand OpenBCommand { get; set; }public DelegateCommand GoBackCommand { get; set; }public DelegateCommand GoForwordCommand { get; set; }public MainWindowViewModel(IRegionManager regionManager){OpenACommand = new DelegateCommand(OpenA);OpenBCommand = new DelegateCommand(OpenB);GoForwordCommand = new DelegateCommand(GoForward);GoBackCommand = new DelegateCommand(GoBack);this.regionManager = regionManager;}public void GoBack(){journal.GoBack();//回到上一步的页面}public void GoForward(){journal.GoForward();//回到下一步的页面}public void OpenA(){//NavigationParameters parm=new NavigationParameters();//parm.Add("Value", "Hello");//传递一个参数,名称为Value,Value的值为Hello/////导航到指定的区域管理器//regionManager.RequestNavigate("ContentRegion", "PageA",parm);//第1个参数是要在哪个区域显示,第2个参数是要显示的页面,第3个是要给参数2要显示的页面传递的参数//注:上面那3行的作用和下面这一行一样regionManager.RequestNavigate("ContentRegion", $"PageA?Value=Hello", arg =>{journal = arg.Context.NavigationService.Journal;//导航日志});//第1个参数是要在哪个区域显示,第2个参数$"PageA?Value=Hello"的作用是:要显示的页面为PageA,传递的一个Value参数值为Hello}public void OpenB(){///导航到指定的区域管理器regionManager.RequestNavigate("ContentRegion", "ViewB", arg =>{journal = arg.Context.NavigationService.Journal;});//第1个参数是要在哪个区域显示,第2个参数是要显示的页面}}
}

10.对话服务Dialog

1.简介

  1. 参考博客
  2. 对话框实际上我们应用程序经常用到的一个功能,类如:Show、ShowDialog,可以弹出一个我们指定的窗口,仅此而已。
    而Prism中提供了一组对话框,封装了常用的对话框组件的功能,例如:
  • RegisterDialog/DialogService(注册对话及使用对话)
  • 打开对话框传递参数/关闭对话框返回参数
  • 回调通知对话结果

2.创建一个对话框

创建并使用一个对话框的步骤举例:
实现效果:
在这里插入图片描述
工程目录如下:
在这里插入图片描述

  1. 添加一个View,这里起名为MsgView
    在这里插入图片描述
    2.添加一个ViewModel类,这里名为:MsgViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;namespace BlankApp1.ViewModels
{public class MsgViewModel : BindableBase,IDialogAware{public DelegateCommand saveCommand { get; set; }public DelegateCommand cancelCommand { get; set; }private string _title;public string Title{get { return _title; }set { _title = value;RaisePropertyChanged(); }}public event Action<IDialogResult> RequestClose;public MsgViewModel(){///当单击“确定”按钮后,对话框返回的结果是ButtonResult.OK,并且会传出一个Value值,该值为Title的值saveCommand = new DelegateCommand(() =>{DialogParameters parm=new DialogParameters();parm.Add("Value",Title);RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parm));});///当单击“取消”按钮后,对话框返回的结果是ButtonResult.NO,不会传出任何值cancelCommand = new DelegateCommand(() =>{RequestClose?.Invoke(new DialogResult(ButtonResult.No));});}/// <summary>/// 允许关闭对话框/// </summary>/// <returns></returns>public bool CanCloseDialog(){return true;}public void OnDialogClosed(){}public void OnDialogOpened(IDialogParameters parameters){var title=parameters.GetValue<string>("Value");//取出往该对话框中传入的参数Value}}
}

3.进入App.xaml.cs的RegisterTypes方法中,将页面注册为对话框:

  containerRegistry.RegisterDialog<MsgView, MsgViewModel>("question");//将MsgView注册对话框组件,并给MsgView起一个别名为question

如图:
在这里插入图片描述
4.修改MainWindowViewModel.cs中的内容,如下:

using System.Windows;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;namespace BlankApp1.ViewModels
{public class MainWindowViewModel : BindableBase{private string _title = "Prism Application";public string Title{get { return _title; }set { SetProperty(ref _title, value); }}private readonly IRegionManager regionManager;IRegionNavigationJournal journal;//区域导航日志private readonly IDialogService dialog;//对话框服务public DelegateCommand OpenACommand { get; set; }public DelegateCommand OpenBCommand { get; set; }public DelegateCommand GoBackCommand { get; set; }public DelegateCommand GoForwordCommand { get; set; }public MainWindowViewModel(IRegionManager regionManager, IDialogService dialig){OpenACommand = new DelegateCommand(OpenA);OpenBCommand = new DelegateCommand(OpenB);GoForwordCommand = new DelegateCommand(GoForward);GoBackCommand = new DelegateCommand(GoBack);this.regionManager = regionManager;this.dialog = dialig;}public void GoBack(){journal.GoBack();//回到上一步的页面}public void GoForward(){journal.GoForward();//回到下一步的页面}/// <summary>/// 当单击“打开A”按钮后,会弹出一个question类型的对话框,///     如果用户关闭对话框时返回的结果是ButtonResult.OK,那么会取出用户在对话框中输入的内容并显示在一个消息框中;///     如果返回的结果是ButtonResult.NO,那么会取出用户在对话框中输入的内容并显示在一个消息框中;/// </summary>public void OpenA(){DialogParameters param=new DialogParameters();dialog.ShowDialog("question", param, arg =>{if (arg.Result == ButtonResult.OK){var val = arg.Parameters.GetValue<string>("Value");MessageBox.Show($"用户输入了:{val}");}else{MessageBox.Show("用户取消了弹窗!");}});//NavigationParameters parm=new NavigationParameters();//parm.Add("Value", "Hello");//传递一个参数,名称为Value,Value的值为Hello/////导航到指定的区域管理器//regionManager.RequestNavigate("ContentRegion", "PageA",parm);//第1个参数是要在哪个区域显示,第2个参数是要显示的页面,第3个是要给参数2要显示的页面传递的参数//注:上面那3行的作用和下面这一行一样//regionManager.RequestNavigate("ContentRegion", $"PageA?Value=Hello", arg =>//{//    journal = arg.Context.NavigationService.Journal;//导航日志//});//第1个参数是要在哪个区域显示,第2个参数$"PageA?Value=Hello"的作用是:要显示的页面为PageA,传递的一个Value参数值为Hello}public void OpenB(){///导航到指定的区域管理器regionManager.RequestNavigate("ContentRegion", "ViewB", arg =>{journal = arg.Context.NavigationService.Journal;});//第1个参数是要在哪个区域显示,第2个参数是要显示的页面}}
}

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

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

相关文章

WPF开发01-WPF界面设计

@目录1.设计一个优美的注册界面1.实现效果2.代码展示2.简易登录按钮设计1.实现效果2.代码展示3.设计一个优美的注册登录界面(连接数据库)1.实现效果2.代码展示4.设计一个简单的在线教育系统界面1.实现效果2.代码展示5. 设计一个Dashboard1.实现效果2.代码展示6.设计一个旋转风…

Web渗透文件上传有哪些漏洞

Web渗透文件上传有以下漏洞:一、绕过文件类型检查漏洞;二、文件名解析漏洞;三、目录穿越漏洞;四、二进制文件漏洞;五、文件上传时的身份验证和授权问题;等等。绕过文件类型检查漏洞会导致应用程序将恶意文件误认为合法文件,从而允许攻击者执行恶意操作。一、绕过文件类型…

上位机开发02-工控知识学习

@目录1.电机减速机、扭矩2.运动控制相关1.运动控制简介2.伺服电机、步进电机1.伺服电机2.步进电机3.总结3.点位运动、连续运动、直线和圆弧插补运动4.软限位和正限位5.脉冲当量、脉冲数、脉冲频率6.回零:光电开关和编码器信号7.前瞻4.运动控制卡1.简介2.运动控制卡和PLC的区别…

5.5

点击查看代码 import numpy as np from scipy.optimize import minimize def objective(x):x1, x2, x3 = xreturn -(2 * x1 + 3 * x1 ** 2 + 3 * x2 + x2 ** 2 + x3) # 定义约束条件 def constraint1(x):x1, x2 = x[:2] # 只取前两个变量x1和x2return 10 - (x1 + 2 * x1 ** 2 …

2.12

代码点击查看代码 import numpy as np from sympy import Matrix, symbols# 定义一个矩阵 A = np.array([[-1,1,0],[-4,3,0],[1,0,2]])# 使用numpy.linalg.eig求解特征值和特征向量 eigenvalues, eigenvectors = np.linalg.eig(A)print("数值解的特征值:", eigenval…

如何处理Linux系统中频繁出现的系统启动失败问题

​面对Linux系统的启动失败问题,执行以下措施:1.分析日志信息,找出原因;2.检查磁盘空间与文件系统;3.验证系统引导文件;4.修复GRUB引导加载器;5.使用恢复模式进行修复。系统启动故障的根本原因往往隐藏在一些细节中,因此关键在于仔细检查并持续修复。1.分析日志信息,找…

webpack打包js代码(ES6-ES5)和vue文件

为什么需要babel?Babel命令行使用Babel插件的使用Babel的预设presetbabel-loaderbabel-preset编写App.vue代码App.vue的打包过程@vue/compiler-sfcresolve模块解析确实文件还是文件夹extensions和alias配置

大华设备视频平台EasyCVR私有化视频平台云端录像、监控存储、回看、计划与配置功能全解析

EasyCVR是TSINGSEE青犀视频在音视频流媒体技术和人工智能领域的深入研发成果,它以出色的视频处理、汇聚和融合能力,在构建视频监控系统方面表现出独特的优势。 大华设备视频平台EasyCVR能够接入高清网络摄像机的RTSP直播流,并且支持多种其他直播流格式,例如RTMP、HTTP-FLV、…

C语言和Groovy在JVM兼容性上的区别

## C语言和Groovy在JVM兼容性上的区别 在探讨C语言和Groovy在JVM(Java虚拟机)兼容性上的差异时,核心观点可以概括为:C语言不直接兼容JVM、Groovy与JVM高度兼容。C语言是一种通用的、过程式的编程语言,它直接编译为机器语言,执行效率高,但它并不直接兼容JVM,这是因为JVM…

如何评价移动端Vue组件库 Vux

Vux,作为一个基于Vue和WeUI的移动端UI组件库,一直被前端开发者广泛使用并讨论。本文从Vux的安装使用、组件丰富性、定制能力、性能优化、社区活跃度和问题反馈六个方面展开深入剖析,以便帮助开发者全面了解其优缺点,并在实际项目中做出更为精准的技术选型。同时,基于市场上…