2010-11-30 23 views
9

Tengo una ventana de WPF que se ejecuta en una secuencia de fondo como una especie de "ventana de notificación" ... cuando se produce un evento, se muestra un mensaje ... un usuario hace clic en el botón "Repetir" y llamo al this.Visibility = Visibility.Collapsed¿Cómo puedo "Ocultar()" una Ventana WPF modal sin que se cierre?

El mismo momento en que oculto la ventana (llamando al this.Hide() o estableciendo el Visibility como se mencionó anteriormente) ... el código "ShowDialog()" libera la ventana y la cierra.

Esto es absolutamente un error en el código de WPF (que he identificado a través del reflector) ... pero mi pregunta permanece. ¿Alguien ha sido capaz de encontrar una solución para este problema?

que he probado muchas cosas y ahora estoy tratando de llegar a YA'LL gente inteligente :)

Respuesta

0

bien, y lo más rápidamente que - a mi jefe (antigua C++ chico torpe que él es) averiguado la respuesta .

Aquí fue el código dentro de mi hilo de fondo (que se establece en modo STA):

// Show dialog - keeps the thread open and shows the window! Yay!!! 
new BeamUI.Notifier.NotifierWindow().ShowDialog(); 

Y aquí es la modificación, que extrañamente suficientes funciona perfectamente :)

// Show... hmm, that shows the window... but how do I keep this thread open? 
new BeamUI.Notifier.NotifierWindow().Show(); 

// ZOMG - a line of code that JUST keeps the thread (and msgpump) going!!! 
System.Windows.Threading.Dispatcher.Run(); 

Y eso es todo.

Este tipo de cosas me hacen odiar a las personas de C++, y me dan ganas de decir simplemente "¡si lo construyeses desde el principio no tendría que buscar una solución alternativa!" (j/k)

+0

Como una explicación de por qué esto funciona ... el insecto ShowDialog que he mencionado en la pregunta no disponer de la ventana, pero acabo de lanzar el thread-message-pump-hold-it-open-dealio. Entonces, ahora que ya no confiamos en dicho "dealio" ...ocultar/mostrar/ocultar/mostrar es todo bueno :) –

+0

No necesita un hilo separado para una ventana de nivel superior (Mostrar). El hilo principal de la interfaz de usuario se encargará de esto, a menos que haya circunstancias de las que no nos haya hablado. – Tergiver

+0

Hay más: las notificaciones necesitan su propio contexto porque, incluso si la interfaz de usuario principal tiene un cuadro de mensaje (otra ventana "ShowDialog"), esta ventana del notificador debe poder responder a los clics, etc. –

6

No puede ocultar un cuadro de diálogo modal. Eso es como preguntar: "¿Cómo llego a 100 mph en reversa?" No lo haces, conduces el auto hacia adelante.

Usar Mostrar, no MostrarDialog. Alternativamente, puede volver a mostrar ShowDialog cuando necesite volver a ser visible.

+0

Puede ocultar un diálogo modal en WinForms ... hay un error * solo * en las ventanas de WPF. –

+3

Ok, la analogía del automóvil era coja, pero el punto es este: un diálogo modal es, por definición, un diálogo que se muestra y que bloquea al usuario de interactuar con otras partes de su aplicación hasta que complete el diálogo. ¿De qué manera el ocultamiento de tal bestia tiene sentido? – Tergiver

+0

Es porque es un "programa dentro del programa" secundario realmente. El usuario usa la aplicación ... pero el servidor puede comunicarse con el usuario y absolutamente requiere y necesita un contexto exclusivo ... significado - MessageBox.Show ("Hola") en el hilo de la interfaz de usuario principal * no puede * (según los requisitos del negocio)) frustrar el servidor enviando una "notificación". –

2

Timothy's Answer is good. Sólo necesitaba para mi scenerio añadir la siguiente

window.Closed += new EventHandler(window_Closed); 
window.Show(); 
System.Windows.Threading.Dispatcher.Run(); 

y luego en el evento ...

void window_Closed(object sender, EventArgs e) 
{ 
    System.Windows.Threading.Dispatcher.ExitAllFrames(); 
} 

que tenía que hacer esto porque estaba colgado en la ejecución después de que el formulario fue muy cerrada .

2
  1. Para mostrar la ventana modal, siempre use ShowDialog().

  2. Uso Close() en lugar de Hide().

  3. controlar el evento FormClosing así:

 
    private void OnFormClosing(object sender, FormClosingEventArgs e) 
    { 
     e.Cancel = true; 
     this.Visible = false; 
    } 
+3

Esto parece una solución de Winforms. WPF usó Visiblity en lugar de Visible. –

+0

¿Qué pasa si el mismo cuadro de diálogo se muestra de nuevo una excepción se produce. – TrustyCoder

Cuestiones relacionadas