Подтвердить что ты не робот

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

Как предотвратить запуск события 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
}

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

4b9b3361

Ответ 1

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

Другой способ сделать это - удалить 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
}

Ответ 2

В VB:

RemoveHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
btn2.Checked = false
AddHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged

Ответ 3

Я столкнулся с этим сообщением после того, как захотел кое-что реализовать. Я регулярно использую 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;
    }
}

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