zoukankan      html  css  js  c++  java
  • C# 有关控件、自定义类事件中的委托链的获取、移除操作

    直接来代码吧,这样干脆直接,也不耽误我午休了。一切尽在源码中。

    public class ControlEventTool
    {
    
        /// <summary>
        /// 移除控件的某类事件, 如Click事件
        /// 2018.3.21
        /// </summary>
        public static void DemoRemoveControlEvents(System.Windows.Forms.Button btn, string eventName = "Click")
        {
            // 检索按钮的事件,这里单击事件的名字是EventClick,要注意的
            Delegate[] invokeList = GetObjectEventList(btn, "Event" + eventName);
            if (invokeList != null)
            {
                foreach (Delegate del in invokeList)
                {
                    // 我已经测试,事件被全部取消了,没有问题。
                    typeof(System.Windows.Forms.Button).GetEvent(eventName).RemoveEventHandler(btn, del);
                }
            }
        }
    
        /// <summary>
        /// 获取控件指定事件的委托列表  
        /// </summary>
        /// <param name="p_Control">对象</param>
        /// <param name="p_EventName">事件名 EventClick、EventDoubleClick、EventMouseMove</param>
        /// <returns>委托列</returns>
        public static Delegate[] GetObjectEventList(Control p_object, string p_EventName)
        {
            PropertyInfo _PropertyInfo;
            FieldInfo fieldInfo;
            EventHandlerList evList;
            Delegate d;
            object _EventList;
    
            _PropertyInfo = p_object.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
            if (_PropertyInfo == null) return null;
            _EventList = _PropertyInfo.GetValue(p_object, null);
    
            if (_EventList == null || !(_EventList is EventHandlerList)) return null;
            evList = (EventHandlerList)_EventList;
            fieldInfo = (typeof(Control)).GetField(p_EventName, BindingFlags.Static | BindingFlags.NonPublic);
            if (fieldInfo == null) return null;
    
            d = evList[fieldInfo.GetValue(p_object)];
            if (d == null) return null;
    
            return d.GetInvocationList();
        }
    
        
    
        public static void PrintControlEventDelegateList(System.Windows.Forms.Button btn, string eventName = "MouseMove")
        {
    
            PropertyInfo pi = btn.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
            EventHandlerList ehl = (EventHandlerList)pi.GetValue(btn, null);//EventClick
    
            FieldInfo fieldInfo = (typeof(System.Windows.Forms.Control)).GetField("Event" + eventName, BindingFlags.Static | BindingFlags.NonPublic);
            Delegate d = ehl[fieldInfo.GetValue(null)];
    
            if (d == null)
            {
                Console.WriteLine("Typed Event "{0}" not exist in target control!", eventName);
                return;
            }
    
            foreach (Delegate del in d.GetInvocationList())
                Console.WriteLine(del.Method.Name);
        }
    
    
    
        /// <summary>
        /// 对于指定类中自定义事件,移除其中的委托链的全部订阅方法,
        /// 或者移除委托链中的指定方法名的订阅。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="c"></param>
        /// <param name="event_name"></param>
        /// <param name="methodname"></param>
        public static void RemoveEvent<T>(T c, string event_name, string methodname = "")
        {
            Delegate[] invokeList = GetObjectEventList_V2(c, event_name);
            if (invokeList == null) return;
    
            foreach (Delegate del in invokeList)
            {
                if (methodname!="" && del.Method.Name != methodname)
                    continue;
                typeof(T).GetEvent(event_name).RemoveEventHandler(c, del);
                //Console.WriteLine("Remove an event of " + event_name);
            }
        }
    
        public static Delegate[] GetObjectEventList_V2(object p_object, string p_EventName)
        {
            FieldInfo _fieldInfo;
            Delegate _ObjDele;
            object _FieldValue;
    
            _fieldInfo = p_object.GetType().GetField(p_EventName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public);
            if (_fieldInfo == null) return null;
            _FieldValue = _fieldInfo.GetValue(p_object);
    
            if (_FieldValue == null || !(_FieldValue is Delegate)) return null;
            _ObjDele = (Delegate)_FieldValue;
    
            return _ObjDele.GetInvocationList();
        }
    
    
    
        #region Demo2
    
    
        public class TEST
        {
            public event EventHandler AA;
    
            public void Foo()
            {
                if (AA!=null)
                {
                    AA(this,new EventArgs()); //invoke the event
                }
            }
        }
    
        public static void DemoUse2()
        {
    
            TEST obj_a = new TEST();
            obj_a.AA += obj_a_AA;
            obj_a.Foo();
    
            RemoveEvent<TEST>(obj_a, "AA");
            obj_a.Foo();
    
            Console.WriteLine("Finished!");
    
        }
    
        static void obj_a_AA(object sender, EventArgs e)
        {
            Console.WriteLine("Evnet rasied!");
        }
       
        #endregion
    
    
        #region Demo
    
        public static void DemoUse()
        {
    
            System.Windows.Forms.Button btn = new System.Windows.Forms.Button();
            btn.Click += new EventHandler(btn_Click);
            btn.Click += new EventHandler(btn_Click2);
            btn.Click += new EventHandler(btn_Click3);
            btn.MouseMove += btn_MouseMove;
            btn.MouseMove += btn_MouseMove2;
    
    
            // print before
            Console.WriteLine("Before");
            PrintControlEventDelegateList(btn);
            PrintControlEventDelegateList(btn, "Click");
    
            // del delegate
            DemoRemoveControlEvents(btn, "Click");
    
            // print after
            Console.WriteLine("After");
            PrintControlEventDelegateList(btn);
            PrintControlEventDelegateList(btn, "Click");
    
    
    
        }
    
        static void btn_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            throw new NotImplementedException();
        }
    
        static void btn_MouseMove2(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            throw new NotImplementedException();
        }
    
        static void btn_Click(object sender, EventArgs e)
        {
            Console.WriteLine("Click1");
        }
    
        static void btn_Click2(object sender, EventArgs e)
        {
            Console.WriteLine("Click2");
        }
    
        static void btn_Click3(object sender, EventArgs e)
        {
            Console.WriteLine("Click3");
        }
    
        #endregion
    
    
    }
  • 相关阅读:
    C语言冒泡排序例子 JIANG
    C语言技巧 JIANG
    ligerui 表格树中 Uncaught TypeError: p.tree.isParent is not a function 纵一苇之所如
    npoi 已删除的功能: /xl/styles.xml 部分的 格式 (样式) 纵一苇之所如
    超过了为 maxJsonLength 属性设置的值。 纵一苇之所如
    MySQL+Canal+RocketMQ+SpringBppt+ElasticSearch+Redis开源整合
    [开源项目发布]Observer:根据map文件测试程序在运行中各个函数的运行时间
    [工作环境搭建]笔记本与台式机共享鼠标与键盘
    探秘C++机制的实现
    自己实现函数钩子
  • 原文地址:https://www.cnblogs.com/arxive/p/9242763.html
Copyright © 2011-2022 走看看