測試代碼: 改為給Control添加擴展方法。 上述代碼,起作用的根本原因在於Component 內有 受保護的欄位Events ,該欄位記錄了附加到該控制項的所有的事件處理函數。 而wpf 控制項中沒有該成員,所以無法使用該方法判斷。但是可以使用UIElement類提供的 AddHandler 和 R ...
public static class ComponentHelper<T> where T : Control { public static bool HaveEventHandler(T control, string eventName, string methodName) { //獲取Button類定義的所有事件的信息 PropertyInfo pi = (typeof(T)).GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic); //獲取Button對象btn的事件處理程式列表 EventHandlerList ehl = (EventHandlerList)pi.GetValue(control, null); //獲取Control類Click事件的欄位信息 FieldInfo fieldInfo = (typeof(Control)).GetField($"Event{eventName}", BindingFlags.Static | BindingFlags.NonPublic); //用獲取的Click事件的欄位信息,去匹配btn對象的事件處理程式列表,獲取btn對象Click事件的委托對象 //事件使用委托定義的,C#中的委托時多播委托,可以綁定多個事件處理程式,當事件發生時,這些事件處理程式被依次執行 //因此Delegate對象,有一個GetInvocationList方法,用來獲取這個委托已經綁定的所有事件處理程式 Delegate d = ehl[fieldInfo.GetValue(null)]; foreach (Delegate del in d.GetInvocationList()) { //判斷一下某個事件處理程式是否已經被綁定到Click事件上 Console.WriteLine(del.Method.Name == methodName); if (del.Method.Name == methodName) { return true; } } return false; } }
測試代碼:
private void button1_Click(object sender, EventArgs e) { MessageBox.Show("Hello,button1_Click"); } private void button3_Click(object sender, EventArgs e) { this.Text += ComponentHelper<Button>.HaveEventHandler(this.button1, nameof(this.button1.Click), nameof(this.button1_Click)); this.Text += this.button1.HaveEventHandler(nameof(this.button1.Click), nameof(this.button1_Click)); }
改為給Control添加擴展方法。
/// <summary> /// 控制項擴展類,判斷某個事件已經綁定了某個事件處理程式 /// <para>Author:xyf</para> /// <para>Time : 2019/04/02 </para> /// <para>Email:[email protected]</para> /// </summary> public static class ComponentHelper { public static bool HaveEventHandler(this Control control, string eventName, string methodName) { //獲取Control類定義的所有事件的信息 PropertyInfo pi = (typeof(Control)).GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic); //獲取Control對象control的事件處理程式列表 EventHandlerList ehl = (EventHandlerList)pi.GetValue(control, null); //獲取Control類Click事件的欄位信息 FieldInfo fieldInfo = (typeof(Control)).GetField($"Event{eventName}", BindingFlags.Static | BindingFlags.NonPublic); //用獲取的Click事件的欄位信息,去匹配btn對象的事件處理程式列表,獲取control對象Click事件的委托對象 //事件使用委托定義的,C#中的委托時多播委托,可以綁定多個事件處理程式,當事件發生時,這些事件處理程式被依次執行 //因此Delegate對象,有一個GetInvocationList方法,用來獲取這個委托已經綁定的所有事件處理程式 Delegate d = ehl[fieldInfo.GetValue(null)]; foreach (Delegate del in d.GetInvocationList()) { //判斷一下某個事件處理程式是否已經被綁定到Click事件上 if (del.Method.Name == methodName) { return true; } } return false; } }
上述代碼,起作用的根本原因在於Component 內有 受保護的欄位Events ,該欄位記錄了附加到該控制項的所有的事件處理函數。
而wpf 控制項中沒有該成員,所以無法使用該方法判斷。但是可以使用UIElement類提供的 AddHandler 和 RemoveHandler方法。
參考鏈接:
https://bbs.csdn.net/topics/370003848
https://www.cnblogs.com/lujin49/archive/2012/02/23/2364185.html
https://blog.csdn.net/weixin_34090643/article/details/86311811
https://blog.csdn.net/wyljz/article/details/49746549