2010-10-08 13 views
7

Mi WPF-aplicación basada en escritorio (4.0) funciona con DB y para ello debe establecer una conexión con SQL Server en el inicio de la aplicación. Por supuesto, esta operación lleva algo de tiempo y el usuario tiene que esperar algunos segundos (3-5) mientras .Net Framework se inicia y se conecta a SQL Server.MessageBox con detalles de excepción desaparece inmediatamente si usa la pantalla de bienvenida en WPF 4.0

Según corresponda en este tipo de casos, decidí utilizar una pantalla de presentación. Agregué una imagen a la solución, establecí la acción de compilación como «Splash screen», compilé mi aplicación, ¡funciona! Si el intento de conectarse a SQL Server falló (por ejemplo, el servidor no está disponible), mi aplicación arroja una excepción y muestro al usuario MessageBox con detalles de advertencia y excepción, el usuario aprieta Aceptar y se apaga 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 adicional añadida, si ejecuto la aplicación mientras SQL Server no está disponible, la aplicación lanza una excepción (como pregunté en mi código), pero MessageBox con notificación aparece durante 1-2 segundos y desaparece sin ninguna interacción del usuario, el usuario incluso no puede leer lo que está escrito en él.

Descubrí que si trato de mostrar 2 MessagBoxes, entonces el primero aparecerá y desaparecerá inmediatamente, pero el segundo permanecerá hasta que el usuario presione OK.

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

Aquí es un organigrama que describe la lógica de mi solicitud:

Sin excepción (buen escenario): pantalla de ejecución de aplicaciones → Splash → si (isConnectedToSQL = true) → Mostrar ventana principal ...

Con excepción (escenario incorrecto): Ejecutar aplicación → Pantalla de bienvenida → if (isConnectedToSQL = false) → Lanzar excepción → Mostrar MessageBox con detalles de excepción → Hacer clic en Aceptar → Cerrar aplicación.

Gracias.

Respuesta

6

El motivo radica en cómo el SplashScreen utiliza BeginInvoke para cerrarse. No pude precisar exactamente dónde se cierra el MessageBox *, pero vi una solución simple:

No use MessageBox.

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

Siga this guideline declarar su propio procedimiento principal y alterar así:

Editado para mostrar cómo se puede pasar información a la 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); 
} 
  • Mi conjetura es que SplashScreen.Show y Application.Run son dos bombas de mensaje separado. El primero termina con una llamada a PostQuitMessage. Eso explica por qué el MessageBox se cierra.
Cuestiones relacionadas