IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Comment désactiver réellement un bouton sous C# Winforms


Sujet :

C#

  1. #1
    Membre à l'essai
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Avril 2020
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Avril 2020
    Messages : 28
    Points : 21
    Points
    21
    Par défaut Comment désactiver réellement un bouton sous C# Winforms
    Bonjour,

    Avec C# winforms, j'essaie de créer une petite application, et j'essaie de désactiver un bouton après avoir cliqué dessus.
    Pour désactiver le bouton, j'utilise la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    button.Enabled = false;
    mais je me rends compte que le bouton est grisé mais pas désactivé car quand je clique dessus, il relance le traitement.

    Comment désactiver réellement un bouton sous C# winforms ?

    Merci.

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    Ajoute button.refresh ou application.doevents après enabled = false et avant le traitement
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 149
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Surprenant comme comportement.

    Dans quel cas cela se produit-il ?

    Comment est géré le code déclenché par l'appui sur le bouton ?

    Car d'après mes tests, Click n'est jamais déclenché quand le bouton est désactivé, que ce soit lors du clic de la souris, l'appui d'entrée lorsque le bouton est celui de validation du formulaire, espace quand on avait le focus dessus avant de le désactiver, ou même le raccourci clavier qu'on a collé sur le bouton...

    J'ai même tenté de changer le Enable alors que le bouton de la souris était déjà enfoncé... Géré les événements MouseClick, KeyPress, DoubleClick... Quand c'est disable, c'est disable, aucun événement ne se déclenche...
    On ne jouit bien que de ce qu’on partage.

  4. #4
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    Peut être dans le cas d’un traitement long avec reclic pendant le traitement
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 149
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    Peut être dans le cas d’un traitement long avec reclic pendant le traitement
    Ah oui, mais alors dans le cas d'un tel traitement, il faut toujours penser à disable le bouton dans la première ligne du click.
    En effet, si on le disable en fin de traitement, on peut recliquer autant de fois qu'on veut tant que le traitement n'est pas terminé... et c'est la fête du slip, on commande des consoles gratos sur Grosbill et tout ça... (ancien bug corrigé depuis très longtemps )

    -- Edit : bah mince, même dans ce cas, marche pas.

    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            private void ToggleColor()
            {
                for (int i = 0; i < 500000; i++) { pictureBox1.BackColor = i % 2 == 0 ? Color.Yellow: Color.Orange ; } /* dure environ 0,5 seconde */
                Thread.Sleep(1000); /* dure environ 1 seconde */
                clicked = !clicked;
                pictureBox1.BackColor = clicked ? Color.Green : Color.Red;
                listBox1.Items.Add("Click!");
                button1.Enabled = false;
            }

    => J'ai beau cliquer comme un âne, ça ne se déclenche qu'une seule fois (contrôlable au contenu du ListBox) avant que le bouton ne soit désactivé...
    Ceci dit, là c'est presque pas normal. Je ne sais pas si ça a toujours bien fonctionné. Je teste avec le Framework 4.8

    Ou alors le traitement est dans un second thread ? Mais dans ce cas, oui, il ne faut surtout pas désactiver le bouton dans le traitement (même pas au début) mais directement dans la première ligne du handler, sinon rien que le temps de démarrer le second thread on peut avoir le temps de cliquer une seconde fois.
    On ne jouit bien que de ce qu’on partage.

  6. #6
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    Après je me suis pas posé sur autant de questions. A question étrange je mets une réponse étrange (recommander doevents c’est aller loin déjà ^^)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Ah oui, mais alors dans le cas d'un tel traitement, il faut toujours penser à disable le bouton dans la première ligne du click.
    En effet, si on le disable en fin de traitement, on peut recliquer autant de fois qu'on veut tant que le traitement n'est pas terminé... et c'est la fête du slip, on commande des consoles gratos sur Grosbill et tout ça... (ancien bug corrigé depuis très longtemps )
    Pour du winform, c'est uniquement valable si le traitement long est asynchrone (via async/await ou un thread dédié par exemple). Dans le cas contraire, le traitement bloque l'interface utilisateur (interface gelé) et les clics ultérieurs seront traités après le traitement, qui aura désactivé le bouton, donc événement ignoré.

    Normalement, mettre la propriété Enabled à false est suffisant pour bloquer un bouton. Si cela ne marche pas, il nous faudrait voir le code pour comprendre ce qui se passe.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  8. #8
    Membre à l'essai
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Avril 2020
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Avril 2020
    Messages : 28
    Points : 21
    Points
    21
    Par défaut
    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    private void buttonWriteFast_Click (object sender, EventArgs e)
    {
      buttonWriteFast.Enabled = false;
      WriteFast();
      buttonWriteFast.Enabled = true;
    }
    sachant que WriteFast() est un traitement qui dure 5 minutes.

    Le bouton est bien grisé, mais quand je clique dessus, le traitement se relancera après la fin du 1er traitement, ce qui prouve que le bouton est toujours actif.

    Comment résoudre ce problème ?

    Merci.

  9. #9
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Le comportement est donc totalement normal. Ton UI est en réalité gelé par le traitement long. Tu désactives le bouton, tu fais le traitement, puis tu le réactives. Ce qu'il faut comprendre c'est que tant que tu es dans ta méthode buttonWriteFast_Click, aucun message n'est traité. Donc quand tu cliques sur ton bouton, les messages sont mis en attente. Une fois la méthode terminée, les messages en attente sont traités. S'il y a des clics sur le bouton, le bouton est donc recliqué car l'état du bouton à ce moment précis sera un état actif.

    Une manière de ne pas avoir le problème, est de réécrire légèrement le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    private async void buttonWriteFast_Click (object sender, EventArgs e)
    {
      buttonWriteFast.Enabled = false;
      await Task.Run(() =>  WriteFast());
      buttonWriteFast.Enabled = true;
    }
    Ainsi, le traitement long sera exécuté sur un thread à part, et ne bloquera pas le thread principal, ce qui permettra aux messages d'événement d'être traité comme il se doit (ici, clic sur bouton ignoré car traité quand le bouton est désactivé).
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  10. #10
    Membre à l'essai
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Avril 2020
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Avril 2020
    Messages : 28
    Points : 21
    Points
    21
    Par défaut
    Merci !
    Je me demandais si c'était aussi possible d'arrêter la fonction en cliquant sur un bouton stop par exemple sous C#. Ce n'est peut-être pas le sujet de ce fil, alors j'ai ouvert une autre discussion. Si tu pouvais regarder, je te remercie.

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/05/2017, 14h39
  2. Comment désactiver l'authenfication LDAP sous jboss
    Par DevServlet dans le forum Wildfly/JBoss
    Réponses: 0
    Dernier message: 29/06/2009, 12h27
  3. Réponses: 13
    Dernier message: 06/07/2006, 17h06
  4. [WinForms]comment savoir sur quel bouton j'ai cliqué?
    Par bossun dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 14/03/2006, 14h18
  5. Comment désactiver Ctrl+Alt+Del sous Windows XP
    Par ETOKA dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 04/06/2003, 13h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo