wpf prism 弹出框(参数支持父传子,子传父)及消息发布、订阅
十年河东,十年河西,莫欺少年穷
学无止境,精益求精
1、新建项目wpfApp6,添加Nuget引用,并初始化App.xaml 及 cs 类
app.cs 如下

public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve<MainView>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterDialog<UserControlA, UserControlAModel>("UserControlA"); } }
app.xaml 如下:

<Prism:PrismApplication x:Class="WpfApp6.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp6" xmlns:Prism="http://prismlibrary.com/" > <Application.Resources> </Application.Resources> </Prism:PrismApplication>
说明如下:
app.cs 中设定了启动窗体
return Container.Resolve<MainView>();
app.cs 中注入了一个对话框,名称为:UserControlA ,并设定了viewModel数据上下文: UserControlAModel
containerRegistry.RegisterDialog<UserControlA, UserControlAModel>("UserControlA");
2、启动窗体
启动窗体必须写在Views文件夹中,且必须以View结尾,启动窗体的viewModel必须放在ViewModels文件夹中,且必须以Model结尾
xaml

<Window x:Class="WpfApp6.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp6.Views" xmlns:Prism="http://prismlibrary.com/" Prism:ViewModelLocator.AutoWireViewModel="true" mc:Ignorable="d" Title="MainView" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal"> <Button Content="点击并弹出用户控件" Margin="5" Height="35" Width="150" Command="{Binding BtnCommand}" CommandParameter="UserControlA"></Button> </StackPanel> </Grid> </Window>
viewModel如下:

public class MainViewModel : BindableBase { /// <summary> /// 窗体Button按钮事件,用于点击后,弹出框 /// </summary> public DelegateCommand<string> BtnCommand { get; set; } /// <summary> /// 引入Prism 的 DialogService 服务,它可以弹出用户控件,或者窗体 /// </summary> private readonly IDialogService dialogService; public MainViewModel(IDialogService dialogService) { BtnCommand = new DelegateCommand<string>(open); this.dialogService = dialogService; } private void open(string obj) { //弹框传递的参数,键值对 IDialogParameters parameters = new DialogParameters(); parameters.Add("schoolId", 1); parameters.Add("schoolName", "河南大学"); //弹出框 并传递参数、设定弹出窗体关闭时的回调函数 dialogService.ShowDialog(obj, parameters,callback); } /// <summary> /// 弹出窗体关闭时的回调函数 /// </summary> /// <param name="result"></param> private void callback(IDialogResult result) { if (result.Result == ButtonResult.OK) { var closeParam = result.Parameters.GetValue<string>("closeParam"); } } }
3、弹出的用户控件
xaml

<UserControl x:Class="WpfApp6.UserControls.UserControlA" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp6.UserControls" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition /> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <TextBlock Text="温馨提示" FontSize="30" Grid.Row="0"/> <TextBlock Text="我是用户控件A" FontSize="30" Grid.Row="1" TextAlignment="Center"/> <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="5"> <Button Height="30" Width="100" Content="确定" Margin="5" Command="{Binding saveCommand}"/> <Button Height="30" Width="100" Content="取消" Margin="5" Command="{Binding cancelCommand}"/> </StackPanel> </Grid> </UserControl>
viewModel如下

using Prism.Commands; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfApp6.UserControlModels { /// <summary> /// 被弹出的框,用户控件 /// </summary> public class UserControlAModel : IDialogAware { public string Title { get; set; } /// <summary> /// 关闭窗体请求事件 /// </summary> public event Action<IDialogResult> RequestClose; /// <summary> /// 保存按钮事件 /// </summary> public DelegateCommand saveCommand { get; set; } /// <summary> /// 取消按钮事件 /// </summary> public DelegateCommand cancelCommand { get; set; } public UserControlAModel() { this.Title = "用户控件A"; saveCommand = new DelegateCommand(save); cancelCommand = new DelegateCommand(cancel); } /// <summary> /// 保存,关闭窗体,并传值给主窗体 /// </summary> private void save() { OnDialogClosed(); } /// <summary> /// 取消,直接关闭窗体 /// </summary> private void cancel() { RequestClose.Invoke(new DialogResult(ButtonResult.No)); } /// <summary> /// 是否可关闭窗体,可以写一些业务逻辑,这里直接返回True /// </summary> /// <returns></returns> public bool CanCloseDialog() { return true; } /// <summary> /// 关闭窗体,并传值给主窗体 /// </summary> public void OnDialogClosed() { IDialogParameters parameters = new DialogParameters(); parameters.Add("closeParam", "我是closeParam值"); RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters)); } /// <summary> /// 窗体打开后,接收主窗体传递的参数,并赋值给窗体的Title属性 /// </summary> /// <param name="parameters"></param> public void OnDialogOpened(IDialogParameters parameters) { var schoolName = parameters.GetValue<string>("schoolName"); var Id = parameters.GetValue<int>("Id"); this.Title = schoolName + "_" + Id; } } }
4、消息发布与订阅
新建Event文件夹并创建如下类
public class MessageEvent : PubSubEvent<string> { }
发布消息
/// <summary> /// 窗体Button按钮事件,用于点击后,弹出框 /// </summary> public DelegateCommand<string> BtnCommand { get; set; } /// <summary> /// 引入Prism 的 DialogService 服务,它可以弹出用户控件,或者窗体 /// </summary> private readonly IDialogService dialogService; /// <summary> /// /// </summary> private readonly IEventAggregator aggregator; public MainViewModel(IDialogService dialogService, IEventAggregator _aggregator) { BtnCommand = new DelegateCommand<string>(open); this.dialogService = dialogService; this.aggregator = _aggregator; } private void open(string obj) { //弹框传递的参数,键值对 IDialogParameters parameters = new DialogParameters(); parameters.Add("schoolId", 1); parameters.Add("schoolName", "河南大学"); //发布一个消息 aggregator.GetEvent<MessageEvent>().Publish("hello 陈大六"); //弹出框 并传递参数、设定弹出窗体关闭时的回调函数 dialogService.ShowDialog(obj, parameters,callback); }
订阅消息
public UserControlA(IEventAggregator aggregator) { var evn = aggregator.GetEvent<MessageEvent>().Subscribe(callback => { MessageBox.Show(callback); }); InitializeComponent(); }
@天才卧龙的博尔乐
分类:
WPF+ModBus
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构