通过反射清除事件订阅

针对Winform,网上介绍的都语焉不详,或者根本不能用,因此研究了一下,贴出来以备参考。

如果你用的自定义类,那么可能事件的处理会有差异,请勿参考下文。后期遇到需要再研究。

记录不易,转载请注明出处。

 https://www.cnblogs.com/honk/p/12776589.html

 

主要用到的是:EventInfo.RemoveEventHandler

也可以使用:System.ComponentModel.EventHandlerList.RemoveHandler

具体代码参考如下:

            //取控件指定 EventInfo
            EventInfo evt = splitButton1.GetType().GetEvent("Click");
            if (evt!=null)
            {
                //取继承的Events属性信息,此属性继承自:System.ComponentModel.Component.Events  (System.ComponentModel.EventHandlerList)
                var li = splitButton1.GetType().GetProperty("Events", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
                if (li != null)
                {
                    //从属性对象中取出实例的事件列表集合
                    System.ComponentModel.EventHandlerList list = (System.ComponentModel.EventHandlerList)li.GetValue(splitButton1, null);

                    //从事件列表中取出对应Key的事件信息
                    //这里可以从Control.Click反编译代码中可以看到:
                    //public event EventHandler Click
                    //{
                    //    add { this.AddHandler("Click", value); }
                    //    remove { this.RemoveHandler("Click", value); }
                    //}
                    Delegate d = list["Click"];

                    //方法1:直接从EventInfo解除订阅
                    evt.RemoveEventHandler(splitButton1, d);

                    //方法2:通过事件列表来清除所有订阅
                    if (d != null)
                    {
                        foreach (Delegate temp in d.GetInvocationList())
                        {
                            list.RemoveHandler("Click", temp);
                        }
                    }
                }
            }

 

posted @ 2020-04-26 02:03  devs  阅读(231)  评论(0编辑  收藏  举报