317 votes

Comment faire pour que le curseur devienne le curseur d'attente ?

Comment puis-je afficher le curseur d'attente/occupé (généralement le sablier) à l'utilisateur pour lui faire savoir que le programme est en train de faire quelque chose ?

558voto

Donut Points 32892

Vous pouvez utiliser Cursor.Current .

// Set cursor as hourglass
Cursor.Current = Cursors.WaitCursor;

// Execute your time-intensive hashing code here...

// Set cursor as default arrow
Cursor.Current = Cursors.Default;

Cependant, si l'opération de hachage est vraiment longue (MSDN définit cette durée comme étant supérieure à 2-7 secondes), vous devriez probablement utiliser un indicateur de retour visuel autre que le curseur pour informer l'utilisateur de la progression. Pour un ensemble de directives plus approfondies, voir cet article .

Edit :
Comme @Am l'a souligné, vous devrez peut-être appeler Application.DoEvents(); après Cursor.Current = Cursors.WaitCursor; pour s'assurer que le sablier est effectivement affiché.

26 votes

Cela ne changera pas nécessairement le curseur - si la boucle de message ne sera pas appelée pendant le code à forte intensité de temps. pour l'activer, vous devez ajouter Application.DoEvents() ; après le premier jeu de curseurs.

17 votes

Vous voudrez probablement essayer de bloquer "..finally" après avoir défini Current, aussi (en s'assurant que Current est remis à Default).

8 votes

Pour info, je n'ai pas réussi à faire fonctionner la méthode ci-dessus, mais en la modifiant en this.cursor = cursors.waitcursor ; cela a fonctionné.

200voto

draganstankovic Points 1948

En fait,

Cursor.Current = Cursors.WaitCursor;

temporairement définit le curseur d'attente, mais ne garantit pas que le curseur d'attente s'affiche jusqu'à la fin de votre opération. D'autres programmes ou commandes au sein de votre programme peuvent facilement ramener le curseur sur la flèche par défaut, comme cela se produit en fait lorsque vous déplacez la souris alors que l'opération est toujours en cours.

Une bien meilleure façon d'afficher le curseur d'attente est de définir la propriété UseWaitCursor d'un formulaire sur true :

form.UseWaitCursor = true;

Cela affichera le curseur d'attente pour tous les contrôles du formulaire jusqu'à ce que vous définissiez cette propriété à false. Si vous voulez que le curseur d'attente soit affiché au niveau de l'application, vous devez utiliser la propriété :

Application.UseWaitCursor = true;

0 votes

C'est bon à savoir. J'ai essayé de faire la même chose dans WPF, et j'ai abouti à Curseur = Cursors.Wait et Curseur = Cursors.Arrow . Mais je n'ai pas trouvé le curseur sous la rubrique App

3 votes

Impossible de trouver UseWaitCursor sous Application !

2 votes

J'ai constaté que, lorsque l'on définit form.UseWaitCursor = false à la fin de l'opération, le curseur n'est pas réellement réinitialisé tant que l'on n'a pas déplacé ou cliqué sur la souris. Par contre, form.Cursor n'a pas ce problème. Je n'ai pas réussi à faire fonctionner Cursor.Current du tout.

44voto

mhapps Points 36

Dans le prolongement de ce qui précède, mon approche préférée (puisqu'il s'agit d'une action fréquemment exécutée) est d'envelopper le code du curseur d'attente dans une classe d'aide IDisposable afin qu'il puisse être utilisé avec using() (une ligne de code), prendre des paramètres facultatifs, exécuter le code à l'intérieur, puis nettoyer (restaurer le curseur) après.

public class CursorWait : IDisposable
{
    public CursorWait(bool appStarting = false, bool applicationCursor = false)
    {
        // Wait
        Cursor.Current = appStarting ? Cursors.AppStarting : Cursors.WaitCursor;
        if (applicationCursor) Application.UseWaitCursor = true;
    }

    public void Dispose()
    {
        // Reset
        Cursor.Current = Cursors.Default;
        Application.UseWaitCursor = false;
    }
}

Utilisation :

using (new CursorWait())
{
    // Perform some code that shows cursor
}

0 votes

1 votes

Je n'avais pas vu ça, mais oui, une approche similaire. Il sauvegarde le curseur actuel puis le restaure, ce qui peut être utile si vous changez souvent de curseur.

36voto

dmihailescu Points 471

Il est plus facile à utiliser UseWaitCursor au niveau du formulaire ou de la fenêtre. Un cas d'utilisation typique peut ressembler à ce qui suit :

    private void button1_Click(object sender, EventArgs e)
    {

        try
        {
            this.Enabled = false;//optional, better target a panel or specific controls
            this.UseWaitCursor = true;//from the Form/Window instance
            Application.DoEvents();//messages pumped to update controls
            //execute a lengthy blocking operation here, 
            //bla bla ....
        }
        finally
        {
            this.Enabled = true;//optional
            this.UseWaitCursor = false;
        }
    }

Pour une meilleure expérience de l'interface utilisateur, vous devez utiliser l'asynchronisme à partir d'un autre thread.

2 votes

Ce devrait être la réponse ACCEPTÉE. C'est la seule qui utilise try-finally.

1 votes

Avez ma upvote, il me manquait un try-finally dans mon implémentation

26voto

Amirshk Points 5379

Mon approche consisterait à effectuer tous les calculs dans un travailleur d'arrière-plan.

Puis changez le curseur comme ceci :

this.Cursor = Cursors.Wait;

Et dans l'événement de fin du fil, restaure le curseur :

this.Cursor = Cursors.Default;

Notez que cela peut également être fait pour des contrôles spécifiques, de sorte que le curseur sera le sablier uniquement lorsque la souris se trouve au-dessus d'eux.

0 votes

@Malfist : bonne approche :), alors tout ce que vous avez à faire est de placer la restauration dans l'événement final, et vous avez terminé.

0 votes

C'est la solution la plus propre si nous avons besoin d'une interface utilisateur réactive et si nous voulons informer que quelque chose est en cours d'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X