Para una vista construida con WPF, quiero cambiar el cursor del mouse a un reloj de arena cuando la aplicación está ocupada y no responde.
Una solución es agregar
this.Cursor = Cursors.Wait;
a todos los lugares que pueden hacer que la interfaz de usuario deje de responder. Pero, obviamente, esta no es la mejor solución. Me pregunto cuál es la mejor manera de lograrlo.
¿Es posible lograr esto usando estilos o recursos?
Gracias,
using(uiServices.ShowWaitCursor())
. Parece engorroso pero facilita las pruebas unitarias.Usé las respuestas aquí para construir algo que funcionó mejor para mí. El problema es que cuando finaliza el bloque de uso en la respuesta de Carlo, es posible que la interfaz de usuario todavía esté ocupada vinculando datos. Es posible que se activen eventos o datos de carga diferida como resultado de lo que se hizo en el bloque. En mi caso, a veces pasaron varios segundos desde que el cursor de espera desapareció hasta que la interfaz de usuario estuvo realmente lista. Lo resolví creando un método de ayuda que configura el cursor de espera y también se encarga de configurar un temporizador que automáticamente restablecerá el cursor cuando la interfaz de usuario esté lista. No puedo estar seguro de que este diseño funcione en todos los casos, pero funcionó para mí:
fuente
Simplemente estoy haciendo
De acuerdo con la documentación de Mouse.OverrideCursor Property
La instrucción try-finalmente asegura que el cursor predeterminado se restaure en cualquier caso, incluso cuando ocurre una excepción o la parte try se deja con
return
obreak
(si está dentro de un bucle).fuente
La mejor manera sería no hacer que la interfaz de usuario no responda nunca, descargando todo el trabajo a otros subprocesos / tareas según corresponda.
Aparte de eso, estás en un catch-22: si agregaste una forma de detectar que la interfaz de usuario no responde, no hay una buena manera de cambiar el cursor, ya que el lugar donde necesitarías hacer eso ( el hilo par) no responde ... ¿Sin embargo, es posible que pueda invocar el código win32 estándar para cambiar el cursor para toda la ventana?
De lo contrario, tendría que hacerlo de forma preventiva, como sugiere su pregunta.
fuente
Personalmente prefiero no ver que el puntero del mouse cambia muchas veces de reloj de arena a flecha. Para ayudar a prevenir ese comportamiento al llamar a funciones incrustadas que toman un tiempo y cada una intenta controlar el puntero del mouse, utilizo una pila (contador) que llamo LifeTrackerStack. Y solo cuando la pila está vacía (contador a 0) que coloco el reloj de arena en una flecha.
También uso MVVM. También prefiero el código seguro para subprocesos.
En mi clase raíz de modelo, declaro mi LifeTrackerStack que pueblo en clases de modelo para niños o lo uso directamente desde clases de modelos para niños cuando tengo acceso a él desde ellas.
Mi rastreador de vida tiene 2 estados / acciones:
Luego, en mi opinión, me vinculo manualmente a mi Model.IsBusy y hago:
Esta es mi clase LifeTrackerStack:
Y el uso de la misma:
En todos los lugares donde corro mucho, hago:
Esto funciona para mi. ¡Espero que pueda ayudar a alguno! Eric
fuente
Tenga cuidado aquí porque jugar con el cursor de espera puede causar algunos problemas con los subprocesos de STA. Asegúrese de que si usa esto, lo está haciendo dentro de su propio hilo. Publiqué un ejemplo aquí Ejecutar dentro de una STA que usa esto para mostrar un WaitCursor mientras se inicia el archivo generado, y no explota (la aplicación principal) AFAICT.
fuente
Cambiar el cursor no significa que la aplicación no responderá a los eventos del mouse y del teclado después de que la tarea de ejecución prolongada haya finalizado. Para evitar que el usuario se engañe, utilizo la siguiente clase que elimina todos los mensajes del teclado y del mouse de la cola de mensajes de la aplicación.
fuente
Usé la solución de Olivier Jacot-Descombes, es muy simple y funciona bien. Gracias. actualización: incluso funciona bien sin usar un subproceso / trabajador en segundo plano diferente.
Lo uso con backgroudworker, el cursor del mouse se ve muy bien cuando está ocupado trabajando y vuelve a la normalidad cuando el trabajo está terminado.
fuente
Sé que llego tarde, acabo de cambiar la forma en que administro el cursor Hourglass (estado ocupado) de mi aplicación.
Esta solución propuesta es más compleja que mi primera respuesta, pero creo que es más completa y mejor.
No dije que tenga una solución fácil o completa. Pero para mí es el mejor porque principalmente soluciona todos los problemas que tuve al administrar el estado ocupado de mi aplicación.
Ventajas:
El código se divide en algunas clases:
Este es el uso:
En eso:
Uso preferido:
Otro uso:
Cursor de ventana automática:
Código:
fuente