欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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方法。


winform判断一个事件是否已经绑定了事件处理函数

 

 

 

 

 

 

参考链接: