2010-01-09 15 views
6

¿Cómo puedo forzar que ShowDialog regrese de un hilo de fondo?WPF - Force ShowDialog para devolver

Tengo una aplicación WPF construida sobre un marco C++/CLR que está escuchando mensajes enviados por el marco. Un mensaje en particular es tan importante que necesito cerrar todas las ventanas actuales. Sin embargo, si un modal Dialog (creado por ShowDialog desde mi ventana principal) está activo y esperando la entrada del usuario, la ventana no se cerrará porque está esperando que regrese el ShowDialog. ¿Cómo puedo forzar el modal Dialog para cerrar y desenrollar la ejecución del código?

Intenté configurar el DialogResult o llamando al Close sin embargo, eso no parece funcionar.

Editar: El Dialog es creado por mi ventana principal, que espera un valor de retorno, así: (dentro de un controlador de eventos click en MainWindow):

Window modalDialog = new Window(); 
bool ret = (bool)modalDialog.ShowDialog(); 
if (ret == true) 
{ 
// do stuff 
} 
else 
{ 
// do some other stuff 
} 

Cuando el marco envía un mensaje (que entra en un hilo diferente que el hilo de UI), llamo al MainWindow.Close(). El diálogo modal se cierra en este punto, sin embargo, el código que verifica el valor de retorno de Dialog (después de ShowDialog) todavía está en la pila. De alguna manera esto obliga a que la ventana principal no desaparezca.

Respuesta

3

Cuando el diálogo recibe el mensaje WM_CLOSE que establece un indicador que causa ShowDialog para volver después de la WM_CLOSE y los mensajes que contienen han sido completamente procesado. Por lo tanto, si está haciendo un Dispatcher.Invoke() en su hilo para llamar al MainWindow.Close(), el ShowDialog() no regresará hasta que se haya completado el Dispatcher.Invoke().

Así que la solución simple es volver desde Dispatcher.Invoke() para obtener el ShowDialog() para devolver. Si se requiere más procesamiento, haga otro Dispatcher.Invoke() inmediatamente después.

si usted está haciendo la transición hilo de alguna otra manera que Dispatcher.Invoke(), o si el ShowDialog() no vuelve después de las Dispatcher.Invoke devuelve la llamada(), puede que tenga que colocar una parte del código que rodea su llamada para que Window.Close() puede ver lo que realmente está haciendo

1

No puede obligar a ShowDialog a regresar, pero puede hacer que la ventana escuche un evento enviado por su marco que puede indicar que se cierre. En el ejemplo siguiente, el evento de progreso tiene un indicador de "Hecho" y cierra la ventana cuando termina.

SomeGenerator IG = Manager.SomeGenerator(); 
SomeWindow PP = new SomeWindow(); 
IG.ProgressEvent += PP.ProgressEvent; 
IG.ExecuteAsync();    
PP.ShowDialog(); 
+0

Modifiqué mi pregunta original para indicar que se esperaba que ShowDialog devolviera un valor y se supone que la ventana principal debe hacer algún procesamiento con el valor ... – Hypherion

0

Ahora me doy cuenta de que no puedo obligar a ShowDialog a regresar y continuar la ejecución cuando quiera. El controlador de eventos para la solicitud que recibo de las necesidades marco está fuera de contexto, por lo que la pila de llamadas se puede desenrollar y el cuadro de diálogo modal puede procesar el mensaje Cerrar.

Terminé configurando un indicador booleano, solicitando que los modales se cierren, luego regrese desde mi controlador de eventos de framework. Solo en este punto, ShowDialog regresará y puedo verificar la bandera que configuro y continuar con la acción solicitada.

+0

Parece que mi respuesta fue la correcta y te ayudó a resolver tu problema . Si acepta, debe marcarlo como "correcto" para futuros visitantes. –

Cuestiones relacionadas