如果在WPF 4.0中使用启动画面,带有exception详细信息的MessageBox会立即消失

我的基于桌面的WPF应用程序(4.0)与DB一起使用,为此应该在应用程序的启动时与SQL Server建立连接。 当然,这个操作需要一些时间,用户必须等待几秒钟(3-5),而.Net Framework启动并连接到SQL Server。

在这种情况下,我决定使用闪屏。 我在解决方案中添加了一些图片,将构建操作设置为“启动画面”,编译了我的应用程序,它的工作原理! 如果连接到SQL Server的尝试失败(例如服务器不可用),我的应用程序将抛出异​​常,并向用户MessageBox显示警告和exception详细信息,用户按OK和应用程序关闭(Application.Current.Shutdown())。

在我添加启动画面之前,所有这些逻辑都可以完美地工作,但现在,添加了启动画面,如果我在SQL Server不可用时运行应用程序,应用程序会抛出exception(正如我在我的代码中提到的那样),但是出现了带有通知的MessageBox持续1-2秒并且在没有任何用户交互的情况下消失,用户甚至无法读取其上写的内容。

我发现,如果我尝试显示2个MessagBoxes,那么第一个将立即出现并消失,但第二个将保持到用户将按OK。

我的问题是:如何解决这个问题? 如果抛出exception,我想使用启动画面并显示一个MessageBox,并让用户决定何时关闭它(用户单击“确定”按钮)。

这是一个描述我的应用程序逻辑的流程图:

没有例外(好的场景):运行app→启动画面→if(isConnectedToSQL = true)→显示主窗口…

有exception(错误情况):运行应用程序→启动画面→如果(isConnectedToSQL = false)→抛出exception→显示带有exception详细信息的消息框→用户单击确定→关闭应用程序。

谢谢。

原因在于SplashScreen如何使用BeginInvoke来关闭它自己。 我无法准确确定MessageBox关闭的位置*,但我确实看到了一个简单的修复:

不要使用MessageBox。

创建一个错误窗口,我们称之为“ErrorWindow.xaml”。 使用该窗口向用户显示错误消息并响应“确定”按钮。

按照此指南声明您自己的主程序并将其更改为:

编辑以显示如何将信息传递给ErrorWindow。

public static void Main() { SplashScreen splashScreen = new SplashScreen("whatever.jpg"); splashScreen.Show(true); string errorMessage; bool dataLoaded = LoadDataFromDatabase(out errorMessage); WpfApplication1.App app = new WpfApplication1.App(); Window windowToRun = dataLoaded ? (Window)new MainWindow() : (Window)new ErrorWindow { ErrorMessage = errorMessage }; app.Run(windowToRun); } 
  • 我的猜测是SplashScreen.Show和Application.Run是两个独立的消息泵。 第一个是通过调用PostQuitMessage终止的。 这就解释了MessageBox关闭的原因。

在类似的StackOverflow问题上,我列出了几种处理此问题的不同方法。

如果@ Tergiver的方法不适用于您的应用程序,您可能会发现其他一些技巧很有用。

如何将wpf MessageBox.Owner设置为桌面窗口,因为SplashScreen关闭了MessageBox

鉴于问题描述在https://connect.microsoft.com/VisualStudio/feedback/details/381980/wpf-splashscreen-closes-messagebox#tabs解决此问题的一种方法是DllImport SetActiveWindow并将其称为SetActiveWindow(IntPtr.Zero) )在调用MessageBox.Show之前。 然后消息框不会将启动屏幕作为其父屏幕,并且当启动屏幕自行关闭时不会消失。