Pour une vue construite à l'aide de WPF, je souhaite changer le curseur de la souris en sablier lorsque l'application est occupée et ne répond pas.
Une solution consiste à ajouter
this.Cursor = Cursors.Wait;
à tous les endroits susceptibles de rendre l'interface utilisateur non réactive. Mais ce n’est évidemment pas la meilleure solution. Je me demande quelle est la meilleure façon d'y parvenir?
Est-il possible d'y parvenir en utilisant des styles ou des ressources?
Merci,
using(uiServices.ShowWaitCursor())
. Cela semble fastidieux mais facilite les tests unitaires.J'ai utilisé les réponses ici pour créer quelque chose qui fonctionnait mieux pour moi. Le problème est que lorsque le bloc using dans la réponse de Carlo se termine, l'interface utilisateur peut en fait être encore occupée à la liaison de données. Des données ou des événements chargés paresseusement peuvent se déclencher suite à ce qui a été fait dans le bloc. Dans mon cas, il a parfois fallu plusieurs secondes pour que le curseur d'attente ait disparu jusqu'à ce que l'interface utilisateur soit réellement prête. Je l'ai résolu en créant une méthode d'assistance qui définit le curseur d'attente et prend également en charge la configuration d'une minuterie qui réinitialisera automatiquement le curseur lorsque l'interface utilisateur sera prête. Je ne peux pas être sûr que cette conception fonctionnera dans tous les cas, mais cela a fonctionné pour moi:
la source
Je fais simplement
Selon la documentation de la propriété Mouse.OverrideCursor
L'instruction try-finally garantit que le curseur par défaut est restauré dans tous les cas, même lorsqu'une exception se produit ou que la partie try est laissée avec
return
oubreak
(si dans une boucle).la source
Le meilleur moyen serait de ne jamais rendre l'interface utilisateur non réactive, en déchargeant tout le travail vers d'autres threads / tâches, le cas échéant.
En dehors de cela, vous êtes en quelque sorte dans un catch-22: si vous avez ajouté un moyen de détecter que l'interface utilisateur n'est pas réactive, il n'y a pas de bon moyen de changer le curseur, car l'endroit où vous auriez besoin de le faire ( le thread pair) n'est pas réactif ... Vous pourrez peut-être épingler le code win32 standard pour changer le curseur pour toute la fenêtre, cependant?
Sinon, vous devrez le faire de manière préventive, comme le suggère votre question.
la source
Personnellement, je préfère ne pas voir le pointeur de la souris passer plusieurs fois du sablier à la flèche. Pour éviter ce comportement lors de l'appel de fonctions intégrées qui prennent un certain temps et qui tentent chacune de contrôler le pointeur de la souris, j'utilise une pile (compteur) que j'appelle un LifeTrackerStack. Et ce n'est que lorsque la pile est vide (compteur à 0) que je remets le sablier en flèche.
J'utilise également MVVM. Je préfère également le code thread-safe.
Dans ma classe racine de modèle, je déclare mon LifeTrackerStack que je remplis des classes de modèle enfant ou que je l'utilise directement à partir des classes de modèle enfant lorsque j'y ai accès à partir d'elles.
Mon tracker de vie a 2 états / actions:
Ensuite, à mon avis, je lie manuellement à mon Model.IsBusy et je fais:
Voici ma classe LifeTrackerStack:
Et son utilisation:
Partout où je fais du jogging prolongé, je fais:
Ça marche pour moi. J'espère que cela pourrait aider n'importe qui! Eric
la source
Soyez prudent ici car le fait de jouer avec le curseur d'attente peut causer des problèmes avec les threads STA. Assurez-vous que si vous utilisez cette chose, vous le faites dans son propre thread. J'ai posté un exemple ici Exécuter dans un STA qui l'utilise pour afficher un WaitCursor pendant le démarrage du fichier généré, et ne fait pas exploser (l'application principale) AFAICT.
la source
La modification du curseur ne signifie pas que l'application ne répondra pas aux événements de la souris et du clavier une fois la longue tâche en cours d'exécution terminée. Pour éviter les erreurs de l'utilisateur, j'utilise la classe ci-dessous qui supprime tous les messages du clavier et de la souris de la file d'attente des messages de l'application.
la source
J'ai utilisé la solution d'Olivier Jacot-Descombes, elle est très simple et fonctionne bien. Merci. mise à jour: cela fonctionne même bien sans utiliser un autre thread / background worker.
Je l'utilise avec backgroudworker, le curseur de la souris a fière allure lorsqu'il est occupé à travailler et revient à la normale lorsque le travail est terminé.
la source
Je sais que je suis en retard, j'ai juste changé la façon dont je gère le curseur Hourglass (état occupé) de mon application.
Cette solution proposée est plus complexe que ma première réponse mais je pense qu'elle est plus complète et meilleure.
Je n'ai pas dit que j'avais une solution facile ou une solution complète. Mais pour moi, c'est le meilleur car il résout principalement tous les problèmes que j'ai rencontrés dans la gestion de l'état occupé de mon application.
Avantages:
Le code est séparé en quelques classes:
Voici l'usage:
Init:
Utilisation préférée:
Autre usage:
Curseur de fenêtre automatique:
Code:
la source