C# 關於獲取控件事件委托列表的一點總結


-- 反射獲取控件事件委托FieldInfo的幾種情況總結
1、通過 ("Event" + EventInfo.Name) 來獲取 FieldInfo
例如: GetField("EventClick") 即可獲取控件Click事件委托字段
2、通過 ("Event" + EventInfo.Name.Replace("Changed","")) 來獲取 FieldInfo
例如: GetField("EventText") 即可獲取控件的TextChanged事件委托字段
3、通過 ("Event" + EventInfo.Name).ToUpper() 來獲取 FieldInfo
例如: GetField("EVENT_SELECTEDINDEXCHANGED") 即可獲取控件的SelectedIndexChanged事件委托字段
4、通過 ("Event" + EventInfo.Name.Replace("Changed","")).ToUpper() 來獲取 FieldInfo
例如: GetField("EVENT_DROPDOWNSTYLE") 即可獲取控件的DropDownStyleChanged事件委托字段
-- CheckBox Event Fields:
EVENT_DROPDOWN
EVENT_DRAWITEM
EVENT_MEASUREITEM
EVENT_SELECTEDINDEXCHANGED
EVENT_SELECTIONCHANGECOMMITTED
EVENT_SELECTEDITEMCHANGED
EVENT_DROPDOWNSTYLE
EVENT_TEXTUPDATE
EVENT_DROPDOWNCLOSED
-- Control Event Fields:
EventAutoSizeChanged
EventKeyDown
EventKeyPress
EventKeyUp
EventMouseDown
EventMouseEnter
EventMouseLeave
EventDpiChangedBeforeParent
EventDpiChangedAfterParent
EventMouseHover
EventMouseMove
EventMouseUp
EventMouseWheel
EventClick
EventClientSize
EventDoubleClick
EventMouseClick
EventMouseDoubleClick
EventMouseCaptureChanged
EventMove
EventResize
EventLayout
EventGotFocus
EventLostFocus
EventEnabledChanged
EventEnter
EventLeave
EventHandleCreated
EventHandleDestroyed
EventVisibleChanged
EventControlAdded
EventControlRemoved
EventChangeUICues
EventSystemColorsChanged
EventValidating
EventValidated
EventStyleChanged
EventImeModeChanged
EventHelpRequested
EventPaint
EventInvalidated
EventQueryContinueDrag
EventGiveFeedback
EventDragEnter
EventDragLeave
EventDragOver
EventDragDrop
EventQueryAccessibilityHelp
EventBackgroundImage
EventBackgroundImageLayout
EventBindingContext
EventBackColor
EventParent
EventVisible
EventText
EventTabStop
EventTabIndex
EventSize
EventRightToLeft
EventLocation
EventForeColor
EventFont
EventEnabled
EventDock
EventCursor
EventContextMenu
EventContextMenuStrip
EventCausesValidation
EventRegionChanged
EventMarginChanged
EventPaddingChanged
EventPreviewKeyDown

  1 /// <summary>
  2 /// 默認反射搜索方式標記
  3 /// </summary>
  4 internal const BindingFlags BindingFlagsDef =
  5     BindingFlags.Instance
  6     | BindingFlags.Static
  7     | BindingFlags.Public
  8     | BindingFlags.NonPublic
  9     | BindingFlags.GetField
 10     | BindingFlags.SetField
 11     | BindingFlags.GetProperty
 12     | BindingFlags.SetProperty
 13     ;
 14     
 15 /// <summary>
 16 /// 獲取對象名稱為 name 的 事件
 17 /// </summary>
 18 /// <param name="obj">對象</param>
 19 /// <param name="name">名稱</param>
 20 /// <param name="bindingFlags">反射搜索方式標記</param>
 21 /// <returns></returns>
 22 public static EventInfo GetEvent(object obj, string name, BindingFlags bindingFlags = BindingFlagsDef)
 23 {
 24     Type type = GetObjType(obj);
 25     try
 26     {
 27         EventInfo Event = bindingFlags.Equals(BindingFlagsDef) ? type.GetEvent(name) : type.GetEvent(name, bindingFlags);
 28         return Event;
 29     }
 30     catch(Exception ex)
 31     {
 32         ConsDebug.WriteErrorLog(ex,$"TypeProp.GetEvent({obj},{name},{bindingFlags})");
 33         return null;
 34     }
 35 }    
 36 /// <summary>
 37 /// 獲取事件的字段信息FieldInfo
 38 /// </summary>
 39 /// <param name="obj"></param>
 40 /// <param name="name"></param>
 41 /// <param name="bindingFlags"></param>
 42 /// <returns></returns>
 43 public static List<FieldInfo> GetEventFields(object obj, string name = "", BindingFlags bindingFlags = BindingFlagsDef)
 44 {
 45     List<FieldInfo> fieldInfos = new List<FieldInfo>();
 46     if (GetEvent(obj, name) is EventInfo eventInfo)
 47     {
 48         string eventName = eventInfo.Name; 
 49         List<string> fields = new List<string>();
 50         foreach (string eName in new string[] {
 51             eventName,
 52             eventName.Replace("Changed","")
 53         })
 54         {
 55             fields.AddRange(new string[] {
 56                 eName,
 57                 $"Event{eName}",
 58                 $"Event_{eName}",
 59                 $"Event_{eName}".ToUpper()
 60             });
 61         }
 62         switch (eventName) 
 63         {
 64             case "TextChanged":
 65                 fields.AddItem("EventText");
 66                 break;
 67             case "SizeChanged":
 68                 fields.AddItem("EventSize");
 69                 break;
 70         }
 71         foreach (string field in fields)
 72         {
 73             //Console.WriteLine($"GetEventField-field:{field}");
 74             foreach (Type type in GetBaseTypes(obj))            // 遍歷對象類型 以及 對象父類類型
 75             {
 76                 if (type.GetField(field, bindingFlags) is FieldInfo fieldInfo)
 77                 {
 78                     //Console.WriteLine($"GetEventField-fieldInfo:{fieldInfo.Name}");
 79                     fieldInfos.AddItem(fieldInfo);
 80                 }
 81             }
 82         }
 83     }
 84     return fieldInfos;
 85 }
 86 /// <summary>
 87 /// 讀取對象指定名稱對應的(事件)委托字典集合
 88 /// </summary>
 89 /// <param name="obj">對象</param>
 90 /// <param name="name">名稱</param>
 91 /// <param name="bindingFlags">反射搜索方式標記</param>
 92 /// <returns></returns>
 93 public static Dictionary<string, Delegate> GetEventDelegate(object obj, string name = "", BindingFlags bindingFlags = BindingFlagsDef)
 94 {
 95     if (obj is null)
 96         return null;
 97     Dictionary<string, Delegate> delegates = new Dictionary<string, Delegate>();
 98     Type type = GetObjType(obj);
 99     try
100     {
101         if (GetEvent(obj, name) is EventInfo eventInfo)
102         {
103             PropertyInfo eventPropInfo = type.GetProperty("Events", bindingFlags);          // 獲取type類定義的所有事件的信息
104             if (eventPropInfo?.GetValue(obj) is EventHandlerList eventHandlerList)          // 獲取對象的事件處理程序列表
105             {
106                 int addCount = 0;
107                 foreach (FieldInfo fieldInfo in GetEventFields(obj, name, bindingFlags) )   // 獲取事件的字段信息
108                 {
109                     object fieldVal = fieldInfo.GetValue(obj);
110                     if (fieldVal != null && eventHandlerList[fieldVal] is Delegate deleg)
111                     {
112                         foreach (Delegate dele in deleg.GetInvocationList())
113                         {
114                             delegates.AddItem(eventInfo.Name, dele, AddMode.KeyIncrement);
115                             addCount++;
116                         }
117                     }
118                 }
119                 if(addCount == 0)
120                 {
121                     delegates.AddItem(eventInfo.Name, null, AddMode.KeyIncrement);
122                 }
123             }
124         }
125     }
126     catch(Exception ex)
127     {
128         ConsDebug.WriteErrorLog(ex, $"TypeProp.GetEventDelegate({obj},{name},{bindingFlags})");
129     }
130     if (name.IsNullOrEmpty())
131     {
132         foreach (EventInfo eventInfo in type.GetEvents())
133         {
134             delegates.AddRange(GetEventDelegate(obj, eventInfo.Name));
135         }
136     }
137     return delegates;
138 }
139 
140 /// <summary>
141 /// Dictionary擴展
142 /// </summary>
143 public static class DictionaryExtension
144 {
145     /// <summary>
146     /// 集合項添加模式枚舉
147     /// </summary>
148     [Description("集合項添加模式枚舉")]
149     [Flags]
150     public enum AddMode
151     {
152         /// <summary>
153         /// 常規
154         /// </summary>
155         [Description("常規")]
156         Normal = 0,
157         /// <summary>
158         /// 唯一(如果鍵值存在,則不添加)
159         /// </summary>
160         [Description("唯一(如果鍵值存在,則不添加)")]
161         Unique = 2,
162         /// <summary>
163         /// 不為空(如果鍵值為空,則不添加)
164         /// </summary>
165         [Description("不為空(如果鍵值為空,則不添加)")]
166         NonNull = 4,
167         /// <summary>
168         /// 不為空或空字符串(如果鍵值為空或空字符串,則不添加)
169         /// </summary>
170         [Description("不為空或空字符串(如果鍵值為空或空字符串,則不添加)")]
171         NonNullOrEmpty = 8,
172         /// <summary>
173         /// 如果鍵值存在,則自動添加自增索引
174         /// </summary>
175         [Description("如果鍵值存在,則自動添加自增索引")]
176         KeyIncrement = 16
177     }
178     internal static string AddModeKeyIncrementDelim = "-";
179     /// <summary>
180     /// 擴展:Dictionary AddItem 
181     /// </summary>
182     /// <param name="dictTarget">目標字典</param>
183     /// <param name="key"></param>
184     /// <param name="val"></param>
185     /// <param name="addMode"></param>
186     /// <param name="mode"></param>
187     public static void AddItem<TKey,TValue>(this Dictionary<TKey, TValue> dictTarget, TKey key, TValue val, AddMode addMode = AddMode.Unique, int mode = 0)
188     {
189         try
190         {
191             if (dictTarget is null || key.IsNullOrEmpty() || key.IsNull())
192                 return;
193             if (val.IsNull() && (addMode & AddMode.NonNull) is AddMode.NonNull)
194                 return;
195             if (val.IsNullOrEmpty(true) && (addMode & AddMode.NonNullOrEmpty) is AddMode.NonNullOrEmpty)
196                 return;
197             if (dictTarget.ContainsKey(key) && (addMode & AddMode.Unique) is AddMode.Unique)
198                 return;
199             if (key is string && (addMode & AddMode.KeyIncrement) is AddMode.KeyIncrement)
200             {
201                 int startsWithKey = 0;
202                 foreach (KeyValuePair<TKey, TValue> kvp in dictTarget)
203                     if (kvp.Key.ToString().StartsWith(key.ToString()))
204                         startsWithKey++;
205                 if (startsWithKey > 0)
206                     key = $"{key}{AddModeKeyIncrementDelim}{startsWithKey}".ConvertTo<TKey>();
207             }
208             if (mode == 0)
209             {
210                 //Console.WriteLine($"AddItem{mode} = ({key},{val})");
211             }
212             dictTarget.Add(key, val);
213         }
214         catch (Exception ex)
215         {
216             ConsDebug.WriteErrorLog(ex,$"DictionaryExtension.AddItem<{typeof(TKey)},{typeof(TValue)}>({dictTarget},{key},{val},{addMode})");
217         }
218     }
219 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM