从控件中取消事件 [英] Unhook the events from a control

查看:110
本文介绍了从控件中取消事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

this.comboBox1.SelectedIndexChanged + = new System.EventHandler(this.comboBox1_SelectedIndexChanged);



以上语句将为事件的控件comboBox1连接事件SelectedIndexChanged如果我们再次写同一个语句,那么方法comboBox1_SelectedIndexChanged将被调用两次,就像我们被触发的SelectedIndexChanged一样。



现在我想unhood / unbind与comboBox1相关的所有事件。



this.comboBox1。 SelectedIndexChanged - = new System.EventHandler(this.comboBox1_SelectedIndexChanged);



使用上面的语句将统一事件一次,所以我想知道我们是否有任何可以解开该控件中的所有事件。



提到的波纹管只是从控件中删除了点击事件。



对象OBJ = f1.GetValue(comboBox1);

的PropertyInfo PI = comboBox1.GetType()的getProperty( 事件,BindingFlags.NonPublic | BindingFlags.Instance);

EventHandlerList list =(EventHandlerList)pi.GetValue(comboBox1,null);

list.RemoveHandler(obj,list [obj]);

解决方案

您没有添加或删除事件;您正在某个事件实例的调用列表中添加或删除处理程序



您只删除一个处理程序只是因为您从未尝试在代码示例中删除另一个。你可以用完全相同的方式删除另一个。让我们考虑您的第一个单行代码示例,其中您使用运算符' - ='。它删除了一个处理程序, this.comboBox1_SelectedIndexChanged 。如果您将同一行与其他处理程序添加到同一事件实例中,而不是 this.comboBox1_SelectedIndexChanged 。如果不存在其他处理程序,则无需删除任何处理程序,否则您应该有一个或多个处理程序。



(一个重要说明:如果您使用匿名方法作为处理程序,你将无法使用这种方法删除它,所以我没有考虑上面这种可能性。)



最后,我建议避免删除事件处理程序,因为通常不需要。它将为您提供使用匿名处理程序的可能性,这些处理程序具有许多好处。如果要暂时禁用一个或所有处理程序的操作,可以添加一些布尔标志并在处理程序本身中对其进行测试:

  bool  handleMyButtonClick =  //   ...  

// ...

myButton.Click + =( sender,eventArgs)= > {
if (!handleMyButtonClick)返回;
// 对此事件进行一些处理
};



实际上,带按钮的代码示例过于模糊。使用按钮,您只需禁用按钮本身即可。但它应该解释你的想法。并且,如果以这种或其他方式向同一事件实例添加多个处理程序,则可以使用更多这样的标记来执行相同操作。这样,您就可以单独禁用某些处理程序并启用其他处理程序。请考虑一下。



-SA


下面提到的代码解决了我的问题。





字段信息F1 = typeof运算(组合框).GetField( EVENT_SELECTEDINDEXCHANGED,BindingFlags.Static | BindingFlags.NonPublic);



object obj = f1.GetValue(comboBox1);

PropertyInfo pi = comboBox1.GetType()。GetProperty(Events,BindingFlags.NonPublic | BindingFlags.Instance);

EventHandlerList列表=(EventHandlerList)pi.GetValue(comboBox1,NULL);

list.RemoveHandler(OBJ,列表[OBJ]);

this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);

The above statement will hookup the event for the control comboBox1 for the event SelectedIndexChanged and if we write the same statement again, then the method "comboBox1_SelectedIndexChanged" will be called twice, as an when the SelectedIndexChanged us being fired.

Now I wanted to unhood/ unbind all the events associated to comboBox1.

this.comboBox1.SelectedIndexChanged -= new System.EventHandler(this.comboBox1_SelectedIndexChanged);

Using the above statement will unhood the event only once, so I wanted to know if any how we can unhook all the events from that control.

The bellow mentioned is removing only the click event from the control.

object obj = f1.GetValue(comboBox1);
PropertyInfo pi = comboBox1.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
EventHandlerList list = (EventHandlerList)pi.GetValue(comboBox1, null);
list.RemoveHandler(obj, list[obj]);

解决方案

You are not adding or removing events; you are adding or removing handlers to/from the invocation list of some event instance.

You remove only one handler simply because you never tried to remove another one in your code sample. And you can remove another one in exact same way. Let's consider your first one-line code sample, where you use the operator '-='. It removes one handler, this.comboBox1_SelectedIndexChanged. If you right the same line with some other handler added to the same event instance, instead of this.comboBox1_SelectedIndexChanged. If another handler does not exist, there is nothing to remove, otherwise you should have one or more of them.

(One important note: if you used anonymous method as a handler, you won't be able to remove it using this approach, so I did not consider such possibility above.)

Finally, I would advise avoid removing the event handlers, as usually this is not needed. And it would open you the possibilities to use anonymous handlers, which have a number of benefits. If you want to temporarily disable operation of one or all of the handlers, you can add some Boolean flag and test it in the handler itself:

bool handleMyButtonClick = //...

//...

myButton.Click += (sender, eventArgs) => {
   if (!handleMyButtonClick) return;
   // do some handling of this event
};


Actually, the code sample with a button is too artificial. With buttons, you can simply disable a button itself. But it should explain you the idea. And, if you add more then one handler to the same event instance in this or other way, you can do the same using more flags like that. This way, you would be able to disable some of the handlers and enable some other, individually. Please just think about it.

—SA


The bellow mentioned code solves my problem.


FieldInfo f1 = typeof(ComboBox).GetField("EVENT_SELECTEDINDEXCHANGED", BindingFlags.Static | BindingFlags.NonPublic);

object obj = f1.GetValue(comboBox1);
PropertyInfo pi = comboBox1.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
EventHandlerList list = (EventHandlerList)pi.GetValue(comboBox1, null);
list.RemoveHandler(obj, list[obj]);


这篇关于从控件中取消事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆