MessageBox con detalles de excepción desaparece inmediatamente si usa la pantalla de bienvenida en WPF 4.0

Mi aplicación WPF basada en el escritorio (4.0) funciona con la base de datos y para ello debe establecer una conexión con SQL Server al inicio de la aplicación. Por supuesto, esta operación toma algún tiempo y el usuario tiene que esperar algunos segundos (3-5) mientras .Net Framework se inicia y se conecta a SQL Server.

Según sea apropiado en este tipo de casos, decidí usar una pantalla de bienvenida. Agregué una imagen a la solución, configuré la acción de comstackción como «Pantalla de bienvenida», compilé mi aplicación, ¡funciona! Si el bash de conexión a SQL Server falló (por ejemplo, el servidor no está disponible), mi aplicación lanza una excepción y le muestro al usuario MessageBox con detalles de advertencia y excepción, el usuario presiona OK y cierra la aplicación (Application.Current.Shutdown ()).

Antes de agregar la pantalla de inicio, toda esta lógica solía funcionar perfectamente, pero ahora, con la pantalla de inicio agregada, si ejecuto la aplicación mientras SQL Server no está disponible, la aplicación lanza una excepción (como pedí en mi código), pero aparece el cuadro de mensaje con una notificación durante 1-2 segundos y desaparece sin la interacción del usuario, el usuario ni siquiera puede leer lo que está escrito en él.

Descubrí que si bash mostrar 2 MessagBoxes, el primero aparecerá y desaparecerá inmediatamente, pero el segundo permanecerá hasta que el usuario presione Aceptar.

Mi pregunta es: ¿Cómo resolver este problema? Quiero usar la pantalla de bienvenida y mostrar un MessageBox si se ha lanzado una excepción y dejar que el usuario decida cuándo cerrarlo (haga clic en el botón Aceptar).

Aquí hay un diagtwig de flujo que describe la lógica de mi aplicación:

Sin excepción (buen escenario): Ejecute la aplicación → Pantalla de bienvenida → if (isConnectedToSQL = true) → Mostrar ventana principal …

Con excepción (mal escenario): Ejecute la aplicación → Pantalla de presentación → if (isConnectedToSQL = falso) → Lanzar excepción → Mostrar cuadro de mensaje con detalles de excepción → El usuario haga clic en Aceptar → Cerrar aplicación.

Gracias.

La razón radica en cómo SplashScreen utiliza BeginInvoke para cerrarse. No pude precisar exactamente dónde se está cerrando el MessageBox *, pero vi una solución simple:

No utilice MessageBox.

Cree una ventana de error, llamémosla “ErrorWindow.xaml”. Use esa ventana para mostrar el mensaje de error al usuario y responder al botón Aceptar.

Siga esta guía para declarar su propio procedimiento principal y modifíquelo así:

Editado para mostrar cómo podría pasar información a la ventana de error.

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); } 
  • Mi conjetura es que SplashScreen.Show y Application.Run son dos bombas de mensajes separadas. El primero termina con una llamada a PostQuitMessage. Eso explica por qué el MessageBox se cierra.

En una pregunta similar de StackOverflow, enumeré varios enfoques diferentes para tratar este problema.

Es posible que algunos de estos otros trucos resulten útiles si el enfoque de @ Tergiver no funciona para su aplicación.

cómo configurar wpf MessageBox.Owner en la ventana del escritorio porque SplashScreen cierra MessageBox

Dada la descripción del problema en https://connect.microsoft.com/VisualStudio/feedback/details/381980/wpf-splashscreen-closes-messagebox#tabs una forma de resolver esto es mediante DllImport SetActiveWindow y llamarlo SetActiveWindow (IntPtr.Zero) ) justo antes de llamar a MessageBox.Show. Entonces, el cuadro de mensaje no obtendrá la pantalla de presentación como su padre y no morirá cuando la pantalla de presentación se cierre.