Comment empêcher le déclenchement de l'événement CheckedChanged lors de la vérification d'un contrôle par programme?

Comment puis-je empêcher le déclenchement de l'événement CheckedChanged lors de la vérification d'un contrôle par programmation?

Je le fais habituellement de la manière suivante.

private bool isFrozen = false;

private void btn1_CheckedChanged(object sender, EventArgs e)
{
    if (isFrozen) 
        return;

    isFrozen = true;
    btn2.Checked = false;
    isFrozen = false;

    // Do some stuff
}

private void btn2_CheckedChanged(object sender, EventArgs e)
{
    if (isFrozen) 
        return;

    isFrozen = true;
    btn1.Checked = false;
    isFrozen = false;

    // Do another stuff
}

Existe-t-il une solution meilleure ou plus commune?

27
demandé sur Peter Mortensen 2011-11-11 06:43:41

3 réponses

Je pense que votre chemin est bien.

Autre façon de le faire est de supprimer le Gestionnaire d'événements avant de les vérifier, puis l'ajouter à nouveau après la vérification. De cette façon élimine le besoin de la variable isFrozen.

private void btn1_CheckedChanged(object sender, EventArgs e)
{
  btn2.CheckedChanged -= btn2_CheckedChanged;
  btn2.Checked = false;
  btn2.CheckedChanged += btn2_CheckedChanged;

    // Do some staff
}

private void btn2_CheckedChanged(object sender, EventArgs e)
{
  btn1.CheckedChanged -= btn1_CheckedChanged;
  btn1.Checked = false;
  btn1.CheckedChanged += btn1_CheckedChanged;

    // Do another staff
}
43
répondu LarsTech 2011-11-11 02:58:48

Dans VB:

RemoveHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
btn2.Checked = false
AddHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
7
répondu ozone 2016-03-07 07:02:26

Je suis tombé sur ce post Après avoir voulu implémenter quelque chose comme ça pendant un moment. J'utilise régulièrement Measurement Studio de National Instruments, et leurs contrôles WinForms qui ont L'événement StateChanging ou StateChanged passent un paramètre de type ActionEventArgs, qui a une action de propriété qui peut prendre trois valeurs: ByKeyboard, ByMouse et Programatic. Ceci est très utile pour déterminer ce qui a causé l'état de la commande. Je voulais reproduire cela dans une norme Case à cocher WinForms.

Voici mon code:

public enum ControlSource
{
    Programatic,
    ByKeyboard,
    ByMouse
}

public class AwareCheckBox : Checkbox
{
    public AwareCheckBox()
            : base()
    {
        this.MouseDown += AwareCheckbox_MouseDown;
        this.KeyDown += AwareCheckbox_KeyDown;
    }

    private ControlSource controlSource = ControlSource.Programatic;

    void AwareCheckbox_KeyDown(object sender, KeyEventArgs e)
    {
        controlSource = ControlSource.ByKeyboard;
    }

    void AwareCheckbox_MouseDown(object sender, MouseEventArgs e)
    {
        controlSource = ControlSource.ByMouse;
    }

    public new event AwareControlEventHandler CheckedChanged;
    protected override void OnCheckedChanged(EventArgs e)
    {
        var handler = CheckedChanged;
        if (handler != null)
            handler(this, new AwareControlEventArgs(controlSource));

        controlSource = ControlSource.Programatic;
    }
}

public delegate void AwareControlEventHandler(object source, AwareControlEventArgs e);

public class AwareControlEventArgs : EventArgs
{
    public ControlSource Source { get; private set; }

    public AwareControlEventArgs(ControlSource s)
    {
        Source = s;
    }
}

Je suis sûr qu'il y a des améliorations à apporter, mais mes tests rudimentaires ont démontré que cela fonctionne. J'ai posté ici simplement au cas où d'autres trébuchent sur ce problème et veulent une façon plus claire de distinguer où le changement a été initié. Tous les commentaires bienvenus.

4
répondu Nick 2016-02-10 15:50:41