1. 程式人生 > >C# 有關控件、自定義類事件中的委托鏈的獲取、移除操作

C# 有關控件、自定義類事件中的委托鏈的獲取、移除操作

ons class 單擊 spa inf += finish ati pre

直接來代碼吧,這樣幹脆直接,也不耽誤我午休了。一切盡在源碼中。

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# 有關控件、自定義類事件中的委托鏈的獲取、移除操作