如何以编程方式检查控件时阻止触发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它有效。 我已经发布在这里,以防万一其他人偶然发现这个问题,并希望有一个更清晰的方法来区分改变的起源。 欢迎任何评论。