CheckedChanged事件中的问题

我有一个复选框,我订阅了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)对用户的鼠标输入和键盘输入做出整齐的响应。 没有重复的代码,不需要订阅多个事件(例如键盘,通过按空格键检查/取消选中CheckBox)

不会。无论这是由您的代码,控件自己的代码还是数据绑定完成,这些属性更改事件都会在属性值发生更改时触发。 通常,它都是相同的代码路径。

但是,如果事件处理程序与更改属性值的代码位于同一个类中,则可以执行的操作是在类中引入一个私有布尔字段,用于指示当前属性更改是否由您的代码或用户。 更改后,您只需重置它。 然后,事件处理程序将查看该字段并确定它是否应该执行任何操作:

 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; // ... } } 

对不起,我不能只是评论迈克尔·布恩的答案,因为我是新来的(没有名声),但是对于它的价值,我强烈倾向于他的解决方案给JohannesRössel’s有几个原因。

1)checkedProgrammatically变量对我来说有点太接近全局了。 没有什么可以阻止另一种方法意外地将其设置为true,从而导致所有事件停止。

2)根据您正在处理的事件数量,您可能会得到很多变量。 更改错误的内容很容易,结果很难调试。

3)当您取消订阅然后重新订阅时,您正在做的事情更加明显。 所有逻辑都在那里,您不需要根据特定条件更改事件处理程序以提前退出。

我已广泛使用这两种方法,从长远来看,我发现迈克尔更容易。

您可以使用MouseClick事件并在该检查中选中复选框的已选中状态。 这种方式不会以编程方式触发,只有在用户手动选中或取消选中复选框时才会调用它。

您可以在更改值programiticaly之前设置布尔变量,并检查比在checkedchanged事件中重置该变量