我有一个复选框并订阅了CheckedChanged事件。事件处理程序在其中执行一些操作。我通过编程方式选中和取消选中复选框(例如:chkbx_Name.Checked = true
),然后触发了CheckedChanged事件。
我希望仅在手动选中或取消选中时触发此事件。是否有任何方法可以避免在编程方式下选中/取消选中时触发此事件?
在设置之前取消订阅事件:
check1.CheckChanged -= check1_CheckChanged;
那么你可以以编程方式设置该值,而不触发复选框的 CheckChanged 事件:
check1.Checked = true;
然后重新订阅:
check1.CheckChanged += check1_CheckChanged;
[编辑:2012年3月29日]
Tanvi的方法存在问题,需要捕获所有手动勾选或取消勾选的源。虽然并不多(只有鼠标单击和用户按下空格键),但你必须考虑从MouseClick和KeyUp(检测空格键)调用重构后的事件。
对于CheckBox(或任何控件),更加优雅的做法是对用户输入的来源(键盘、鼠标等)保持不可知性,因此我将使CheckBox属性的编程设置真正成为编程。例如,您可以将属性的编程设置封装到扩展方法中:
static class Helper
{
public static void SetCheckProgrammatically(
this CheckBox c,
EventHandler subscribedEvent, bool b)
{
c.CheckedChanged -= subscribedEvent; // unsubscribe
c.Checked = b;
c.CheckedChanged += subscribedEvent; // subscribe
}
}
使用这种方法,您的代码可以通过一个事件(即CheckChanged)整洁地响应用户的鼠标输入和键盘输入,无需重复代码,无需订阅多个事件(例如键盘,通过按空格键选中/取消选中复选框)。class Foo : Form {
private bool checkedProgrammatically = false;
void someMethod() {
// ...
checkedProgrammatically = true;
checkBox1.Checked = true;
checkedProgrammatically = false;
// ...
}
private void checkBox1_CheckChanged(object sender, EventArgs e) {
if (checkedProgrammatically) return;
// ...
}
}
很抱歉,由于我在这里还是新手(没有声望),所以不能仅仅评论Michael Buen的答案,但就其价值而言,我强烈倾向于他的解决方案,原因如下:
1)checkedProgrammatically变量对我来说有点太接近全局了。没有任何方法可以阻止另一个方法意外将其设置为true,导致所有事件停止。
2)根据您处理的事件数量,您可能会得到许多变量。更改错误的变量很容易,结果可能难以调试。
3)取消订阅然后重新订阅时,您正在做什么更加明显。所有逻辑都在那里,您不需要根据某些条件提前更改事件处理程序。
我已经广泛使用了这两种方法,我发现Michael的方法在长期运行中更容易。
在程序中改变值之前,您可以设置布尔变量,并在CheckedChanged事件中检查和重置该变量。