当前位置: 首页 > news >正文

WPF/C#:使用Stylet中的IWindowManager用于显示等待窗体、对话框与消息框

前言

显示等待框意义

在创建WPF应用的时候,如果我们要执行一个耗时的操作,那么给用户显示一个等待窗体是很常见的需求,通过显示一个等待窗体让用户明白运行的这个软件并没有崩溃,能有效消除用户的焦虑与不确定性,同时能极大提升用户体验,展示软件的专业性和品质,将无聊的等待转化为可预期的、安心的过程。

显示对话框意义

对话框能有效地捕获用户焦点。作为模态窗口,它会强制用户必须完成当前任务(如确认、输入信息或做出选择),之后才能继续操作主窗口。这保证了关键业务流程(如保存文件前的确认)的完整性,防止用户误操作。其次,对话框是信息收集与展示的专用容器。它将特定任务(如设置、登录、详情查看)的UI元素和逻辑封装起来,使主窗口界面保持简洁,同时提升了代码的模块化和可维护性。

显示信息框意义

信息框的核心价值在于即时性与强制性。对于操作成功、失败或出现警告等重要反馈,它能立刻捕获用户注意力,通过模态显示确保用户看到并处理该信息,避免了关键提示被忽略。其次,它为用户提供了快速决策的途径。除了纯信息展示,信息框可附带“是/否”、“确定/取消”等按钮,让用户在不离开当前上下文的情况下,就能对简单询问做出迅速回应,如确认删除操作。

Stylet介绍

Stylet是一个轻量级、高性能的MVVM框架,专为WPF设计。它摆脱了传统MVVM的样板代码,通过基于约定的特性,使得View和ViewModel的自动关联、依赖注入等变得极其简单。开发者几乎无需配置即可快速上手,其内置的功能如IConductor屏幕管理和事件聚合器,能优雅地处理复杂的应用程序导航与模块间通信。Stylet的目标是让开发者专注于业务逻辑本身,而非繁琐的框架配置,从而显著提升WPF应用的开发效率与代码质量。

本文通过使用Stylet内置的IWindowManager可以很容易实现这个需求。

显示等待框

要显示等待窗体那么必须先做一个等待窗体。

创建一个WaitingView.xaml:

<Window x:Class="Rouyan.Pages.View.WaitingView"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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"xmlns:local="clr-namespace:Rouyan.Pages.View"mc:Ignorable="d"Title="WaitingWindow" Height="200" Width="350"WindowStyle="ToolWindow"WindowStartupLocation="CenterScreen"ResizeMode="NoResize"Topmost="True"><Grid><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><Border Grid.Row="0"Background="{DynamicResource PrimaryHueMidBrush}"Padding="16 8"><TextBlock HorizontalAlignment="Center"Text="{Binding Text}"FontSize="16"/></Border><!-- 进度条区域 --><StackPanel Grid.Row="1"Orientation="Vertical"HorizontalAlignment="Center"VerticalAlignment="Center"Margin="20"><ProgressBar Style="{StaticResource MaterialDesignCircularProgressBar}"Foreground="{DynamicResource SecondaryHueMidBrush}"Width="60"Height="60"IsIndeterminate="True"/><TextBlock Text="请稍候..."FontSize="14"HorizontalAlignment="Center"Foreground="{DynamicResource MaterialDesignBody}"Margin="0,10,0,0"/></StackPanel></Grid>
</Window>

效果:

分为两行,上面一行用于显示要显示的信息,下面一行用于显示ProgressBar与"请稍候..."的组合。

现在再来创建对应的ViewModel:

 public class WaitingViewModel : Screen{      public string Text { get; set; } = "处理中...";}

显示这个等待窗体,比如当我们运行一个耗时任务的时候,可以先显示这个等待窗体给用户:

 // 显示等待窗体          waitingVm = _container.Get<WaitingViewModel>();waitingVm.Text = "正在分析请求,请稍候...";_windowManager.ShowWindow(waitingVm);

显示等待窗体主要使用了Stylet中自带的一个组件IWindowManager,我们可以在构造函数中进行依赖注入:

private readonly IContainer _container;
private readonly IWindowManager _windowManager;public TerminalAgentViewModel(IContainer container,IWindowManager windowManager)
{_container = container;_windowManager = windowManager;
}

由于等待窗体是一个Window,因此需要使用IWindowManager的ShowWindow方法。

Stylet会帮我们将所有View与ViewModel都以瞬态的形式注入依赖注入容器中了,因此可以不用自己在这里new一个viewmodel而是可以直接从容器中取一个出来:

 waitingVm = _container.Get<WaitingViewModel>();

IWindowManager的ShowWindow方法的使用,反直觉的一点是传入的不是这个窗体,而是这个窗体对应的ViewModel,Stylet会根据这个ViewModel自动找到对应的View,这也体现了Stylet中ViewModel First的思想。

效果:

这时候可能会有一个疑问就是那么怎么关闭这个窗体呢?

如果是获取对应的Window,我们调用close方法就可以了,现在获取的是对应的ViewModel该如何关闭这个窗体呢?

Stylet已经考虑到了这一个,只要这样写就可以关闭这个窗体:

 waitingVm.RequestClose();

显示对话框

使用Stylet中的IWindowManager显示对话框同样也很简单。

首先创建一个HumanApprovalDialogView:

<Window x:Class="Rouyan.Pages.View.HumanApprovalDialogView"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:s="https://github.com/canton7/Stylet"mc:Ignorable="d"Title="{Binding Title}"Height="200"Width="420"WindowStartupLocation="CenterOwner"ResizeMode="NoResize"Topmost="True"><Window.InputBindings><KeyBinding Command="{s:Action Approve}" Key="Y"/><KeyBinding Command="{s:Action Reject}" Key="N"/></Window.InputBindings><Grid Margin="16"><Grid.RowDefinitions><RowDefinition Height="*"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><!-- 顶部消息行 --><ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto"><TextBlock Text="{Binding Message}"TextWrapping="Wrap"FontSize="14"/></ScrollViewer><!-- 底部按钮行:左侧同意,右侧拒绝 --><Grid Grid.Row="1" Margin="0,16,0,0"><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Button Grid.Column="0"Content="同意(Y)"Width="100"Height="30"HorizontalAlignment="Left"IsDefault="True"Command="{s:Action Approve}"/><Button Grid.Column="1"Content="拒绝(N)"Width="100"Height="30"HorizontalAlignment="Right"IsCancel="True"Command="{s:Action Reject}"/></Grid></Grid>
</Window>

效果:

创建对应的ViewModel:

public class HumanApprovalDialogViewModel : Screen
{public HumanApprovalDialogViewModel(){Title = "执行审批";}private string _title = string.Empty;public string Title{get => _title;set => SetAndNotify(ref _title, value);}private string _message = string.Empty;public string Message{get => _message;set => SetAndNotify(ref _message, value);}// Approve the actionpublic void Approve(){RequestClose(true);}// Reject the actionpublic void Reject(){RequestClose(false);}
}

使用方式与ShowWindow也很相似:

var dialogVm = new HumanApprovalDialogViewModel
{Title = "函数调用审批",Message = $"是否同意这个操作?"
};bool? result = _windowManager.ShowDialog(dialogVm);

最大的区别就是模态与非模态。

模态:
当一个模态窗口(如对话框)出现时,它会独占用户的操作焦点。在用户完成该窗口的任务(例如点击“确定”或“取消”)并关闭它之前,无法与应用程序的其他任何窗口进行交互。程序流程也会在此处暂停,等待窗口关闭后返回结果。这就像一个强制性的“选择题”,你必须回答才能继续。常见场景包括文件保存、确认删除等需要用户明确决策的流程。

非模态:
非模态窗口则像一个开放的助手。它显示后,用户可以随时在它和应用程序的其他窗口之间自由切换,无需关闭它。程序也会继续执行,不会被窗口的开启或关闭打断。这就像一个可以随时查阅的“便签”或“计算器”。它常用于工具箱、属性面板或辅助信息窗口,让用户在主任务进行时能方便地获取额外功能或信息。

简言之就是模态就是会阻塞程序运行,要你明确给一个反馈,非模态不会阻塞程序的运行,就单纯显示一个窗体。

效果:

同意就返回true,拒绝或者关闭窗体就返回false。

显示信息框

我们可以发现IWindowManager除了有ShowWindow与ShowDialog方法外还有一个ShowMessage方法,现在来看下这个方法的使用吧!!

1、基本用法 - 只显示消息

_windowManager.ShowMessageBox("你好");

效果:

2、带标题的消息框

_windowManager.ShowMessageBox("操作完成", "提示");

效果:

3、带确认和取消按钮的消息框

 var result1 = _windowManager.ShowMessageBox("确定要删除这个文件吗?", "确认删除",MessageBoxButton.OKCancel, MessageBoxImage.Question);

效果:

4、带是/否/取消按钮和警告图标的消息框

var result2 = _windowManager.ShowMessageBox("文件已修改,是否保存?", "保存确认",MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);

效果:

5、带自定义按钮标签的消息框 (使用YesNoCancel按钮以展示更多选项)

var customButtons = new Dictionary<MessageBoxResult, string>
{{ MessageBoxResult.Yes, "继续" },{ MessageBoxResult.No, "停止" },{ MessageBoxResult.Cancel, "取消" }
};
var result3 = _windowManager.ShowMessageBox("检测到潜在风险,是否继续操作?", "安全警告",MessageBoxButton.YesNoCancel, MessageBoxImage.Exclamation, MessageBoxResult.No, MessageBoxResult.Cancel, customButtons);

效果:

6、带文本对齐和流方向的消息框

_windowManager.ShowMessageBox("这是一个从右到左显示的消息框文本", "RTL示例",MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.None, MessageBoxResult.None,null, FlowDirection.RightToLeft, TextAlignment.Center);

效果:

7、完整参数示例

 var fullResult = _windowManager.ShowMessageBox("这是一个完整的消息框示例,包含了所有参数的使用","完整示例",MessageBoxButton.OKCancel,MessageBoxImage.Information,MessageBoxResult.OK,MessageBoxResult.Cancel,null,FlowDirection.LeftToRight,TextAlignment.Left);

效果:

最后

本文梳理了Stylet中IWindowManager的用法,分别是ShowWindow、ShowDialog与ShowMessageBox希望对你有所帮助。

http://www.hskmm.com/?act=detail&tid=36475

相关文章:

  • Flask笔记
  • 0253-CLAP-统计参数出现次数
  • 《Vuejs设计与实现》第 18 章(同构渲染)(上) - 详解
  • 配置git
  • 01-C程序设计语言-第2版-第1章导言笔记
  • 0252-CLAP-标记类型的参数
  • 记录我适配iOS26遇到的一些问题
  • 什么情况下有必要使用抽象基类ABC?
  • 0251-CLAP-使用 Cargo 配置
  • vscode安装element报错
  • 2025 年最新推荐!论文发表机构口碑重磅发布,覆盖 SCI / 核心等多领域助你高效发表毕业/SSCI/SCI期刊/核心期刊论文发表机构推荐
  • 2025 年期刊发表机构最新推荐口碑排行榜:覆盖 SCI/SSCI/ 核心期刊,助力科研人员高效选靠谱平台核心期刊发表/国际期刊发表机构推荐
  • 因果机器学习模型实战测试与比较
  • 笔记本电脑如何连接打印机?安装指南分享给你!
  • 2025 年麦克风厂家最新推荐榜单:覆盖娱乐 / 演出 / 直播 / 会议多场景,精选技术领先口碑优良品牌助力采购
  • 【2025-10-21】维护关系
  • 【Github热门项目】DeepSeek-OCR项目上线即突破7k+星!突破10倍无损压缩,重新定义文本-视觉信息处理
  • MATLAB 的无人机 PID 控制及智能 PID 控制器设计的仿真
  • 2025年口碑好的直角支架铝型材深加工,工业铝型材深加工工厂-江苏龙新铝业
  • 2025 年最新工矿灯生产厂家口碑推荐榜:精选 LED/防爆/高光效等多类型产品,助力企业选出实力与品质兼具的照明品牌
  • 2025年10月胰腺癌治疗医生对比榜:五名专家深度解析
  • 2025年10月胰腺癌治疗医生榜单:五强排名与实用决策指南
  • FreeSql 迁移表结构 (非严谨版)
  • 【CTF作业记录】
  • 2025年康明斯厂家权威推荐榜单:覆盖发电机组、发动机及配件全系列产品,技术实力与售后服务深度解析
  • 2025年发电机厂家权威推荐榜:柴油发电机组/康明斯/玉柴/高压/大功率发电机,专业实力与市场口碑深度解析
  • image watch自定义
  • 基于混沌单纯形法改进的布谷鸟搜索算法
  • 中国开发者如何选择最适合的代码管理工具?四大平台横向评测
  • 2025年散热模组厂家推荐排行榜:CPU散热模组,显卡散热模组,服务器散热模组,工业设备散热模组公司推荐