Как предотвратить запуск события CheckedChanged при программной проверке элемента управления? - PullRequest
29 голосов
/ 11 ноября 2011

Как предотвратить событие CheckedChanged при программной проверке элемента управления?

Обычно я делаю это следующим образом.

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
}

Есть ли лучшее или более распространенное решение?

Ответы [ 3 ]

48 голосов
/ 11 ноября 2011

Я думаю, что у вас все в порядке.

Другой способ сделать это - удалить EventHandler перед проверкой, а затем снова добавить его после проверки.Этот способ устраняет необходимость в переменной 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
}
7 голосов
/ 15 апреля 2015

В VB:

RemoveHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
btn2.Checked = false
AddHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
5 голосов
/ 10 февраля 2016

Я наткнулся на этот пост после желания реализовать что-то подобное некоторое время. Я регулярно использую Measurement Studio от National Instruments, и их элементы управления WinForms, у которых событие StateChanging или StateChanged передают параметр типа ActionEventArgs, у которого есть свойство Action, которое может принимать три значения: ByKeyboard, ByMouse и Programatic. Это очень полезно при определении причин изменения состояния элемента управления. Я хотел повторить это в стандартном флажке WinForms.

Вот мой код:

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;
    }
}

Я уверен, что есть улучшения, но мое элементарное тестирование показало, что это работает. Я написал здесь просто на тот случай, если другие натолкнутся на эту проблему и захотят более четкого определения того, где было инициировано изменение. Любые комментарии приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...