2013-03-26 50 views
1

我想要獲得分配給控制的事件的名稱 例如:我有兩種形式AB表格B包含GridControl和gridcontrol有一些事件,如gridControl1_Validating如何訪問控件的事件?

我的目標就是要知道什麼是事件分配給控制

我的代碼如下 形成

public Control[] FilterControls(Control start, Func<Control, bool> isMatch) 
    { 
     var matches = new List<Control>(); 
     Action<Control> filter = null; 
     (filter = new Action<Control>(c => 
     { 
      if (isMatch(c)) 
       matches.Add(c); 
      foreach (Control c2 in c.Controls) 
       filter(c2); 
     }))(start); 

     return matches.ToArray(); 


    } 


    static void main[] 
    { 


     Control[] FoundControls = null; 
     FoundControls = FilterControls(TF, c => c.Name != null && c.Name.StartsWith("grid")); 

     var eventinfo = FoundControls[0].GetType().GetEvent("gridControl1.Validating", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

    } 

有關編譯我得到我的控制,但我得到空at eventinfo 雖然gridcontrol事件有這個事件form B

請幫助

+0

這可能會幫助您:HTTP:// stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control – Anuraj 2013-03-26 05:37:32

回答

0

嘗試的"Validating"代替"gridControl1.Validating"

var eventinfo = FoundControls[0].GetType().GetEvent(
    "Validating", 
    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

雖然這有沒有關係,你有附加一個事件處理該事件的事實。你正在接受事件本身,而不是附屬的處理程序。對於eventInfo變量(其他的添加和刪除其他事件處理程序)您可以做任何有用的事情。

要訪問連接處理程序(基本代表),你需要看一下該事件的實現代碼(使用像ReflectordotPeek,或使用Microsoft Reference Source反編譯):

public event CancelEventHandler Validating 
{ 
    add 
    { 
     base.Events.AddHandler(EventValidating, value); 
    } 
    remove 
    { 
     base.Events.RemoveHandler(EventValidating, value); 
    } 
} 

原來的Control類使用類型爲EventHandlerList的名爲Events的屬性來存儲基於密鑰(在此例中爲EventValidating字段)的所有代表。

要檢索事件的代表,我們應該從Events財產閱讀:

public static Delegate[] RetrieveControlEventHandlers(Control c, string eventName) 
{ 
    Type type = c.GetType(); 
    FieldInfo eventKeyField = GetStaticNonPublicFieldInfo(type, "Event" + eventName); 
    if (eventKeyField == null) 
    { 
     eventKeyField = GetStaticNonPublicFieldInfo(type, "EVENT_" + eventName.ToUpper()); 
     if (eventKeyField == null) 
     { 
      // Not all events in the WinForms controls use this pattern. 
      // Other methods can be used to search for the event handlers if required. 
      return null; 
     } 
    } 
    object eventKey = eventKeyField.GetValue(c); 
    PropertyInfo pi = type.GetProperty("Events", 
     BindingFlags.NonPublic | BindingFlags.Instance); 
    EventHandlerList list = (EventHandlerList)pi.GetValue(c, null); 
    Delegate del = list[eventKey]; 
    if (del == null) 
     return null; 
    return del.GetInvocationList(); 
} 

// Also searches up the inheritance hierarchy 
private static FieldInfo GetStaticNonPublicFieldInfo(Type type, string name) 
{ 
    FieldInfo fi; 
    do 
    { 
     fi = type.GetField(name, BindingFlags.Static | BindingFlags.NonPublic); 
     type = type.BaseType; 
    } while (fi == null && type != null); 
    return fi; 
} 

public static List<Delegate> RetrieveAllAttachedEventHandlers(Control c) 
{ 
    List<Delegate> result = new List<Delegate>(); 
    foreach (EventInfo ei in c.GetType().GetEvents()) 
    { 
     var handlers = RetrieveControlEventHandlers(c, ei.Name); 
     if (handlers != null) // Does it have any attached handler? 
      result.AddRange(handlers); 
    } 
    return result; 
} 

最後一個方法將提取所有連接到控制事件的事件處理程序。這包括來自所有類的處理程序(甚至由winforms內部附加)。您也可以通過處理器的目標對象篩選列表:

public static List<Delegate> RetrieveAllAttachedEventHandlersInObject(Control c, object handlerContainerObject) 
{ 
    return RetrieveAllAttachedEventHandlers(c).Where(d => d.Target == handlerContainerObject).ToList(); 
} 

現在你可以在formB定義gridControl1所有的事件處理程序:

RetrieveAllAttachedEventHandlersInObject(gridControl1, formB); 
+0

這是我的解決方案..但我的問題是我可以知道什麼是與網格相關的所有其他事件? – Rohit 2013-03-26 05:40:25

+0

你想要「附有事件處理程序的所有事件列表」或「所有附加事件處理程序列表」嗎? – 2013-03-26 05:46:24

+0

是的所有這些事件被分配給網格...我嘗試做var eventinfo = FoundControls [0] .GetType()。GetEvents();但它給出了列出的所有事件 – Rohit 2013-03-26 05:48:31