How to obtain the invocation list of any event

14,920

Solution 1

I dont know why the people say it's not possible:

Lets say you want to disable any event temporary, you can create a method like this:

static Delegate[] DisableEvents(this Control ctrl, string eventName)
{
        PropertyInfo propertyInfo = ctrl.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
        EventHandlerList eventHandlerList = propertyInfo.GetValue(ctrl, new object[] { }) as EventHandlerList;
        FieldInfo fieldInfo = typeof(Control).GetField("Event"+eventName, BindingFlags.NonPublic | BindingFlags.Static);

        object eventKey = fieldInfo.GetValue(ctrl);
        var eventHandler = eventHandlerList[eventKey] as Delegate;
        Delegate[] invocationList = eventHandler.GetInvocationList();
        foreach (EventHandler item in invocationList)
        {
            ctrl.GetType().GetEvent(eventName).RemoveEventHandler(ctrl, item);
        }
        return invocationList;

}|

You can call it like this:

var events = textbox1.DisableEvents("GotFocus")

If you want to add them again you just need to go through the events list.

Solution 2

The approach described in the previous answer works perfectly. However, to use it, you need to be sure that the event is implemented not as a field, but as a property. At the same time, the reference to the delegate is stored in the internal object of the Dictionary class. You can read more here: How to: Use a Dictionary to Store Event Instances (C# Programming Guide)

Share:
14,920
Ponraja
Author by

Ponraja

Updated on July 25, 2022

Comments

  • Ponraja
    Ponraja almost 2 years

    How to get the delegate list form event of the control in WPF.

    I have tried the following code but it will return the field info as null

    TextBox cont = new TextBox();
    cont.TextChanged += new TextChangedEventHandler(cont_TextChanged);
    FieldInfo fi = cont.GetType().GetField("TextChanged", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
    Delegate del = (Delegate)fi.GetValue(cont);
    
  • Roy Dictus
    Roy Dictus over 9 years
    What do you mean in that final sentence, "just go through the events list"?
  • Admin
    Admin about 9 years
    I meant that you can iterate the the list that you got in the DisableEvents method and Add those events again. But actually now there is an easiest way to do that and is by calling GetInvocationList to retrieve all the delegates.
  • Alex
    Alex over 6 years
    Works for me! Tested with simple Control.Click event. +1
  • codymanix
    codymanix over 4 years
    this is not a generic way, it only works with Windows.Form.Controls (But it is what OP wanted)