Share via


Get a list of Delegate on Event

Question

Friday, June 16, 2006 5:11 PM | 1 vote

Ok, What I want to do is retreive all the delegate that is attached to an event.

Let's say i'm attaching several deletages to a button:

IE:

myButton.Click += new System.EventHandler(this.myButtonClick1_Click);

myButton.Click += new System.EventHandler(this.myButtonClick2_Click);

myButton.Click += new System.EventHandler(this.myButtonClick3_Click);

myButton.Click += new System.EventHandler(this.myButtonClick4_Click);

Is there any way I can get my 4 eventHandler later on in the code ?

Something like ArrayList EventHandler myButton.Click.GetAllDelegates(); ????

I need to get the list because I want to clear all the delegates from a point that is associate with the event but since I don't have access to the event, I can't write myButton.Click = null; // clear all events.

Any idea on that one ?

thanks.

All replies (10)

Friday, June 16, 2006 5:18 PM | 2 votes

EventHandler handler = myButton.Click;
Delegate[] delegates = e.GetInvocationList();


Friday, June 16, 2006 5:31 PM

Receiving a Error 2 The event 'System.Windows.Forms.Control.KeyPress' can only appear on the left hand side of += or -= Y:\EC2IS\Code\EC2ISBase\EC2ISBase\Controls\EC2ISTextBox.cs 75 39 EC2ISBase
error:

Here's my code:

// remove all the handlers

TextBox tb;

EventHandler handler = tb.KeyPress;

if (handler != null)

{

Delegate[] allDelegates = handler.GetInvocationList();

for (int i = 0;i < allDelegates.Length;i++)

tb.KeyPress -= new System.Windows.Forms.KeyPressEventHandler(allDelegates);

}


Friday, June 16, 2006 6:31 PM

you dont need to know what delegates are attached to clear them all (maybe if you wanted to selectively clear them).

myButton.Click += null;

that will set your click event's delegate to null, thus removing all delegates previously added.


Friday, June 16, 2006 7:10 PM

You cannot access the list of event handlers from outside the class.  Events only allow you to add to and take away from an event.  Internally, you can treat the event as a delegate, and so you can access all its members.  Much of the confusion over this arises from the fact that C# allows you to omit the definition of an event's add and remove operators (which is implicitly implemented using a delegate that is visible from within the class via the same name as the event).  You can make the delegate accessible from outside the class by declaring a property that returns the event's handlers as a delegate, but this wont work for classes defined by the .NET Framework, since they cannot be modified.

Also I haven't tested this, but myButton.Click += new EventHandler(null); should not work, because += does not set the event handler, just adds to its list of handlers.  If it does work, could someone explain why?


Friday, June 16, 2006 7:35 PM

Sorry I didn't try out the code first.  I looked at some possibilities with Reflection, but I couldn't find anything that would work.


Friday, June 16, 2006 8:00 PM

System.Reflection.Assembly asm;
// point the asm to the correct assembly, like GetExecutingAssembly or LoadFrom
asm.GetType().GetEvents // You will need to use the correct GetType override


Friday, June 16, 2006 8:11 PM

sorry, the syntax is wrong (what I get for trying to remember anything)... its

myButton.Click += null;

 Nimrand wrote:
Also I haven't tested this, but myButton.Click += new EventHandler(null); should not work, because += does not set the event handler, just adds to its list of handlers. If it does work, could someone explain why?

EDIT:: ok this is bothering me... click checks for null before combining the value so for click it does not work, but most other event handlers it does.

 

public EventHandler MyEvent;

is the same as:

EventHandler myEvent;

public event EventHandler MyEvent {
    [MethodImplOptions(MethodImplOptions.Synchronized)]
    add {
        myEvent = (EventHandler)Delegate.Combine(myEvent, value);
    }
    [MethodImplOptions(MethodImplOptions.Synchronized)]
    remove {
        myEvent = (EventHandler)Delegate.Remove(myEvent, value);
    }
}

and therefore when you combine a null value with the original value you end up with a null (and therefore cleared out) event handler...


Friday, June 16, 2006 8:40 PM

 Steve Whitley wrote:

and therefore when you combine a null value with the original value you end up with a null (and therefore cleared out) event handler...

I don't mean to be picky, but that doesn't appear to be right.  A null value combined with the original value will return an original value, which is what I would expect.  The documentation for the Combine method states: "A new delegate with an invocation list that concatenates the invocation lists of a and b in that order. Returns a if b is a null reference (Nothing in Visual Basic), returns b if a is a null reference, and returns a null reference if both a and b are null references. "


Friday, June 16, 2006 8:58 PM

hrm...

looking at it now, you seem to be right, but I know i've successfully used this before.

having a bit of a John Nash moment here.


Friday, June 16, 2006 9:51 PM

this will clear them all:

void RemoveClickEvent(Button b) {
    FieldInfo f1 = typeof(Control).GetField("EventClick",BindingFlags.Static|BindingFlags.NonPublic);
    object obj = f1.GetValue(b);
    PropertyInfo pi = button1.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
    EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
    list.RemoveHandler(obj, list[obj]);
}