如何以编程方式检查控件时阻止触发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 } 

有更好或更常见的解决方案吗?

我觉得你的路很好。

另一种方法是在检查之前删除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 } 

在VB中:

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

在想要实现这样的事情一段时间后,我遇到了这篇文章。 我经常使用National Instruments的Measurement Studio,以及具有事件StateChanging或StateChanged的WinForms控件传递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; } } 

我确信有一些改进,但我的初步测试certificate它有效。 我已经发布在这里,以防万一其他人偶然发现这个问题,并希望有一个更清晰的方法来区分改变的起源。 欢迎任何评论。