winform判断一个事件是否已经绑定了事件处理函数
程序员文章站
2022-03-20 09:39:26
测试代码: 改为给Control添加扩展方法。 上述代码,起作用的根本原因在于Component 内有 受保护的字段Events ,该字段记录了附加到该控件的所有的事件处理函数。 而wpf 控件中没有该成员,所以无法使用该方法判断。但是可以使用UIElement类提供的 AddHandler 和 R ......
public static class componenthelper<t> where t : control { public static bool haveeventhandler(t control, string eventname, string methodname) { //获取button类定义的所有事件的信息 propertyinfo pi = (typeof(t)).getproperty("events", bindingflags.instance | bindingflags.nonpublic); //获取button对象btn的事件处理程序列表 eventhandlerlist ehl = (eventhandlerlist)pi.getvalue(control, null); //获取control类click事件的字段信息 fieldinfo fieldinfo = (typeof(control)).getfield($"event{eventname}", bindingflags.static | bindingflags.nonpublic); //用获取的click事件的字段信息,去匹配btn对象的事件处理程序列表,获取btn对象click事件的委托对象 //事件使用委托定义的,c#中的委托时多播委托,可以绑定多个事件处理程序,当事件发生时,这些事件处理程序被依次执行 //因此delegate对象,有一个getinvocationlist方法,用来获取这个委托已经绑定的所有事件处理程序 delegate d = ehl[fieldinfo.getvalue(null)]; foreach (delegate del in d.getinvocationlist()) { //判断一下某个事件处理程序是否已经被绑定到click事件上 console.writeline(del.method.name == methodname); if (del.method.name == methodname) { return true; } } return false; } }
测试代码:
private void button1_click(object sender, eventargs e) { messagebox.show("hello,button1_click"); } private void button3_click(object sender, eventargs e) { this.text += componenthelper<button>.haveeventhandler(this.button1, nameof(this.button1.click), nameof(this.button1_click)); this.text += this.button1.haveeventhandler(nameof(this.button1.click), nameof(this.button1_click)); }
改为给control添加扩展方法。
/// <summary> /// 控件扩展类,判断某个事件已经绑定了某个事件处理程序 /// <para>author:xyf</para> /// <para>time : 2019/04/02 </para> /// <para>email:qwergoodboy@qq.com</para> /// </summary> public static class componenthelper { public static bool haveeventhandler(this control control, string eventname, string methodname) { //获取control类定义的所有事件的信息 propertyinfo pi = (typeof(control)).getproperty("events", bindingflags.instance | bindingflags.nonpublic); //获取control对象control的事件处理程序列表 eventhandlerlist ehl = (eventhandlerlist)pi.getvalue(control, null); //获取control类click事件的字段信息 fieldinfo fieldinfo = (typeof(control)).getfield($"event{eventname}", bindingflags.static | bindingflags.nonpublic); //用获取的click事件的字段信息,去匹配btn对象的事件处理程序列表,获取control对象click事件的委托对象 //事件使用委托定义的,c#中的委托时多播委托,可以绑定多个事件处理程序,当事件发生时,这些事件处理程序被依次执行 //因此delegate对象,有一个getinvocationlist方法,用来获取这个委托已经绑定的所有事件处理程序 delegate d = ehl[fieldinfo.getvalue(null)]; foreach (delegate del in d.getinvocationlist()) { //判断一下某个事件处理程序是否已经被绑定到click事件上 if (del.method.name == methodname) { return true; } } return false; } }
上述代码,起作用的根本原因在于component 内有 受保护的字段events ,该字段记录了附加到该控件的所有的事件处理函数。
而wpf 控件中没有该成员,所以无法使用该方法判断。但是可以使用uielement类提供的 addhandler 和 removehandler方法。
参考链接:
下一篇: 解决多线程复杂问题的一个方法