Ventana de progreso modal de WPF
Pido disculpas si esta pregunta ha sido respondida muchas veces, pero parece que no puedo encontrar una respuesta que funcione para mí. Me gustaría crear una ventana modal que muestre varios mensajes de progreso mientras mi aplicación realiza tareas de larga ejecución. Estas tareas se ejecutan en un hilo separado y puedo actualizar el texto en la ventana de progreso en diferentes etapas del proceso. La comunicación entre hilos está funcionando bien. El problema es que no puedo hacer que la ventana esté solo sobre otras ventanas de aplicaciones (no todas las aplicaciones en la computadora), permanecer en la parte superior, evitar la interacción con la ventana principal y aún permitir que el trabajo continúe.
Esto es lo que he intentado hasta ahora:
Primero, mi ventana de inicio es una clase personalizada que extiende la clase de Windows y tiene métodos para actualizar el cuadro de mensaje. Al principio, creo una nueva instancia de la clase de bienvenida y la muestro / oculto según sea necesario.
En el más simple de los casos, instalo la ventana y llamo.Show()
en eso:
//from inside my secondary thread
this._splash.Dispatcher.Invoke(new Action(() => this._splash.Show());
//Do things
//update splash text
//Do more things
//close the splash when done
this._splash.Dispatcher.Invoke(new Action(() => this._splash.Hide());
Esto muestra correctamente la ventana y continúa ejecutando mi código para manejar las tareas de inicialización, pero me permite hacer clic en la ventana principal y poner eso al frente.
Luego intenté deshabilitar la ventana principal y volver a habilitar más tarde:
Application.Current.Dispatcher.Invoke(new Action(() => this.MainWindow.IsEnabled = false));
//show splash, do things, etc
Application.Current.Dispatcher.Invoke(new Action(() => this.MainWindow.IsEnabled = true));
Esto desactiva todos los elementos de la ventana, pero aún puedo hacer clic en la ventana principal y colocarla delante de la pantalla de bienvenida, que no es lo que quiero.
A continuación, intenté usar la propiedad superior en la ventana de inicio. Esto lo mantiene delante de todo, y junto con la configuración de la propiedad de la ventana principal IsEnabled, podría evitar la interacción, pero esto hace que la pantalla de inicio aparezca delante de TODO, incluidas otras aplicaciones. Yo tampoco quiero eso. Solo quiero que sea la ventana superior dentro de ESTA aplicación.
Luego encontré publicaciones sobre el uso de.ShowDialog()
en lugar de.Show()
. Intenté esto, y se mostró correctamente el cuadro de diálogo y no me permitió hacer clic en la ventana principal, sino en llamar.ShowDialog()
hace que el programa se cuelgue esperando a que cierre el cuadro de diálogo antes de que continúe ejecutando el código. Esto es obviamente, no es lo que yo quiero tampoco. Supongo que podría llamarShowDialog()
en un hilo diferente para que ese hilo se cuelgue pero el hilo que realiza el trabajo no ... ¿es ese el método recomendado?
También he considerado la posibilidad de no usar una ventana y en su lugar colocar un elemento de ventana de tamaño completo delante de todo lo demás en la página. Esto funcionaría, excepto que tengo otras ventanas que abro y me gustaría poder usar la pantalla de inicio cuando también estén abiertas. Si utilizara un elemento de ventana, tendría que volver a crearlo en todas las ventanas y no podría utilizar mi manoUpdateSplashText
Método en mi clase de bienvenida personalizada.
Así que esto me lleva a la pregunta. ¿Cuál es la forma correcta de manejar esto?
Gracias por su tiempo y perdón por la larga pregunta, pero los detalles son importantes :)