c# winform 反射获取事件注册的所有委托,清除注册的事件委托,手动触发指定事件

这个方法应该是最全面的了,写这个的初衷是为了注销事件所绑定的静态事件方法,避免内存泄露.

但是网上的大多只有一个粗略的获取 EventHandlerList 的方法,对于复杂情况的自定义类或者派生类无法准确获取.

this object control  用 object 是为了兼容自定义类里的事件

     /// <summary>
        /// 清空控件所有事件的处理方法.
        /// 默认过滤掉 "Disposed"
        /// </summary>
        /// <param name="control"></param>
        /// <param name="fifterEvents">需要跳过的事件,事件名包含即可,不区分大小写</param>
        public static void ClearEvent(this object control, List<string> fifterEvents)
            {
            var type = control.GetType();
            var events = type.GetEvents();
            foreach(var evt in events)
                {
                if (fifterEvents != null && fifterEvents.Any(f => evt.Name.IndexOf(f, StringComparison.OrdinalIgnoreCase) > -1))
                    continue;
                var InvocationList = control.GetEventInvocationList(evt.Name);
                if (InvocationList == null || InvocationList.Length == 0)
                    continue;
                foreach(var deleg in InvocationList)
                    {
                    evt.RemoveEventHandler(control, deleg);
                    }
                }
            } 
        /// <summary>
        /// 清空控件指定事件下的事件处理方法
        /// </summary>
        /// <param name="control"></param>
        /// <param name="eventname"></param>
        public static void ClearEvent(this object control, string eventname)
            {
            var InvocationList = control.GetEventInvocationList(eventname);
            if (InvocationList == null)
                return;
            Type controlType = control.GetType();
            EventInfo eventInfo = controlType.GetEvent(eventname);
            foreach (Delegate dx in InvocationList)
                eventInfo.RemoveEventHandler(control, dx);
            }

        /// <summary>
        /// 手动触发控件的指定事件
        /// </summary>
        /// <param name="control"></param>
        /// <param name="eventname"></param>
        /// <param name="e">事件参数,一般第一个参数sender默认为控件,所以就省略了,只需要传第二个参数</param>
        public static void TriggerEvent(this object control, string eventname, object e)
            {
            var InvocationList = control.GetEventInvocationList(eventname);
            if (InvocationList == null)
                return;
            foreach (Delegate dx in InvocationList)
                dx.DynamicInvoke(control, e);
            }

        /// <summary>
        /// 获取指定事件的委托
        /// </summary>
        /// <param name="control"></param>
        /// <param name="eventname"></param>
        /// <returns></returns>
        public static Delegate[] GetEventInvocationList(this object control, string eventname)
            {
            if (control == null) return null;
            if (string.IsNullOrEmpty(eventname)) return null;

            Type controlType = control.GetType();
            return GetEventInvocationList(control, controlType, eventname);
            }
        public static Delegate[] GetEventInvocationList(this object control, Type controlType, string eventname)
            {
            if (string.IsNullOrEmpty(eventname)) return null;

            BindingFlags mPropertyFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.IgnoreCase;
            BindingFlags mFieldFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.IgnoreCase;
            PropertyInfo propertyInfo = controlType.GetProperty("Events", mPropertyFlags);
            if (propertyInfo == null)
                {
                if (controlType.BaseType.FullName == "System.Object")
                    return null;
                return GetEventInvocationList(control, controlType.BaseType, eventname);
                }
            EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(control, null);

            FieldInfo fieldInfo = controlType.GetField("Event" + eventname, mFieldFlags);
            if (fieldInfo == null) fieldInfo = controlType.GetField("Event_" + controlType.Name + eventname, mFieldFlags);//有的控件时需要加上控件类型名作为事件名,
            if (fieldInfo == null) fieldInfo = controlType.GetField(eventname, mFieldFlags);//也许有的不需要加前缀
            if (fieldInfo == null)
                {
                //有的必须递归从 BaseType 才能取到事件字段
                if (controlType.BaseType.FullName == "System.Object")
                    return null;
                return GetEventInvocationList(control, controlType.BaseType, eventname);
                }
            var fieldInfoValue = fieldInfo.GetValue(control);
            Delegate d = eventHandlerList[fieldInfoValue];
            if (d == null) return null;

            return d.GetInvocationList();
            }

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值