Wednesday, January 27, 2016

Displaying a message box while a splash screen is visible

If you use a splash screen while your WPF application is initializing you may have noticed a problem when you try to show a messagebox while the splash screen is visible. Perhaps the initialization process failed in Application_Startup.

The problem is that the splash screen is the active window and it is designed to disappear as soon as the first visual element is displayed. By default, message boxes are owned by the active window. You can see what happens. The message box is owned by the splash screen, the splash screen disappears as soon as the message box is displayed, so the message box disappears too.

For me, the problem is made worse because I have an unhandled exception handler defined for the application so any unhandled exception is handled by the same code whether it was raised while the splash screen was visible or later.

Private Sub Application_DispatcherUnhandledException(sender As Object, e As System.Windows.Threading.DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
    ShowFatal(e.Exception.Message)
End Sub

The ShowFatal method simply displays a MessageBox. When the exception originates while the splash screen is displayed the message box disappears before the user can read it. They launch the application, something flashes, and the application exits. Not cool.

The trick is to know that the MainWindow does not yet exist during initialization. In fact, it is the creation of the main window that makes the splash screen go away. So if the main window is not yet created we display a dummy message box that attaches to the splash screen and causes the splash screen to go away. Then we display the proper message box.

Public Shared Sub ShowFatal(sMsg As String)
   ' If the main window is not yet displayed then show a dummy messagebox
    If Application.Current.MainWindow Is Nothing Then System.Windows.MessageBox.Show("")

    System.Windows.MessageBox.Show(sMsg, "Fatal Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Stop)
    Application.Current.Shutdown(1)

End Sub

No comments:

Post a Comment