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