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 }
你们的评论、反馈,及对你们有所用,是我整理材料和博文写作的最大的鼓励和唯一动力。欢迎讨论和关注!
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。