2012-11-13 77 views
1

我想知道哪些方法已被分配來處理控件的事件(來自外部),然後分配相同的方法來處理相同的事件另一種控制。我嘗試了以下方法但沒有成功:如何獲得控制器的處理方法來處理另一個控件的相同事件

private void ReflectMethods(Control control, Control baseControl, string[] excludedEventNames = null, string[] includedEventNames = null) 
{ 
    Type baseType = baseControl.GetType(); 
    Type ownType = control.GetType(); 

    foreach (EventInfo baseEventInfo in baseType.GetEvents()) 
    { 
     if (excludedEventNames != null && excludedEventNames.Contains(baseEventInfo.Name)) 
      continue; 

     if (includedEventNames != null && !includedEventNames.Contains(baseEventInfo.Name)) 
      continue; 

     // 
     // Checking if current control has the same event.. 
     // 
     foreach (EventInfo ownEventInfo in ownType.GetEvents()) 
     { 
      if (ownEventInfo.Name == baseEventInfo.Name) 
      { 
       FieldInfo eventField = baseType.GetField(baseEventInfo.Name, BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance); 

       // The above line always returns null, so I cannot get the handler ??? 
       EventHandler eventHandler = (EventHandler)eventField.GetValue(baseControl); 

       ownEventInfo.AddEventHandler(this, eventHandler); 
      } 
     } 
    } 
} 

回答

1

只要您使用的控件是由您實施的,您的解決方案就很好。發生這種情況是因爲編譯器爲您可以訪問的每個事件創建一個字段,就像您在發佈的代碼中一樣。但這不是你能做到的唯一方法。這就像屬性一樣:每個屬性通常都有一個字段,但這不是唯一的方法。

在Control的情況下,要獲取與事件關聯的委託,您必須通過Events屬性獲取EventHandlerList,然後使用名稱由字符串組成的字段的值來獲取正確的EventHandler, 「事件」後跟事件的實際名稱(例如,對於單擊,您必須查找「EventClick」字段)。

在這裏您可以找到適用於WinForm控件的代碼的修改版本。請注意,它不適用於您自己設計的控件。您應該結合這兩種方法來管理所有情況。

private void ReflectMethods(Control control, Control baseControl, string[] excludedEventNames = null, string[] includedEventNames = null) 
    { 
     Type baseType = baseControl.GetType(); 
     Type ownType = control.GetType(); 

     EventHandlerList events = typeof(Control).GetProperty("Events", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic).GetValue(baseControl, null) as EventHandlerList; 
     foreach (EventInfo baseEventInfo in baseType.GetEvents()) 
     { 
      if (excludedEventNames != null && excludedEventNames.Contains(baseEventInfo.Name)) 
       continue; 

      if (includedEventNames != null && !includedEventNames.Contains(baseEventInfo.Name)) 
       continue; 

      // 
      // Checking if current control has the same event.. 
      // 
      foreach (EventInfo ownEventInfo in ownType.GetEvents()) 
      { 
       if (ownEventInfo.Name == baseEventInfo.Name) 
       { 
        object eventField = typeof(Control).GetField("Event" + baseEventInfo.Name, BindingFlags.NonPublic | BindingFlags.Static).GetValue(baseControl); 
        Delegate aDel = events[eventField]; 
        ownEventInfo.AddEventHandler(control, aDel); 
       } 
      } 
     } 
    } 
+0

+1感謝您的富有表現力的解決方案。 – Mimi

相關問題