如何在APP.xaml Startup函数中顺序弹出两个ShowDialog窗口?应用异常退出排查
问题根源分析
这个问题我之前帮不少开发者排查过,核心和WPF应用的关闭机制直接相关:WPF默认把第一个启动并显示的窗口(也就是你的StartUpWindow)设为Application.Current.MainWindow,而应用默认的ShutdownMode是OnMainWindowClose——意思是只要主窗口关闭,整个应用就会触发退出逻辑。哪怕你用ShowDialog()打开了MainWindow,只要StartUpWindow还是默认主窗口,它一关闭,WPF就会直接终止应用,完全不管其他窗口的状态。
修复现有代码的两种方案
如果你想保留当前的调用逻辑,可以通过以下两种方式快速解决:
1. 修改应用的ShutdownMode
把应用的关闭触发条件改成“最后一个窗口关闭时才退出”,这样就算StartUpWindow关闭,只要MainWindow还在运行,应用就会继续。
你可以在App.xaml里直接配置:
<Application x:Class="YourAppNamespace.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ShutdownMode="OnLastWindowClose"> <!-- 其他原有内容 --> </Application>
或者在代码里动态设置:
Application.Current.ShutdownMode = ShutdownMode.OnLastWindowClose;
2. 手动将MainWindow设为应用主窗口
在打开MainWindow后,主动把它替换成应用的主窗口,这样WPF就会以MainWindow的关闭作为应用退出的触发条件:
// 在StartUpWindow的代码逻辑里 var mainWindow = new MainWindow(); // 替换默认主窗口 Application.Current.MainWindow = mainWindow; mainWindow.ShowDialog(); // 此时关闭StartUpWindow,应用不会退出,因为MainWindow才是新的主窗口
更优的实现方式(推荐)
其实更规范、更可控的做法是手动接管应用的启动流程,避免依赖WPF的默认主窗口逻辑。具体步骤如下:
- 打开
App.xaml,删除StartupUri属性(我们要自己控制启动); - 在
App.xaml.cs里重写OnStartup方法,清晰控制窗口流转:
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // 先显示启动窗口 var startupWindow = new StartUpWindow(); // 假设启动窗口用DialogResult标识用户是否完成启动流程(比如登录成功) if (startupWindow.ShowDialog() == true) { // 启动流程确认,创建并显示主窗口 var mainWindow = new MainWindow(); Application.Current.MainWindow = mainWindow; mainWindow.Show(); } else { // 用户取消启动,直接关闭应用 Application.Current.Shutdown(); } }
这种方式的优势很明显:
- 逻辑清晰直观,启动流程完全由你掌控;
- 明确设置主窗口,彻底避免默认行为带来的意外;
- 可以根据启动窗口的结果灵活处理(比如用户取消登录就直接退出,不用加载主窗口)。
内容的提问来源于stack exchange,提问作者DiniMad
相关产品推荐
相关产品推荐

