2

Before you start asking why in the world I want to do this, bear in mind I don't have much experience with Windows.Forms and at this point I am just experimenting.

Let's say I form with 5 buttons. And like every button, it should do something once I press it. I found out I could add multiple methods to an event such as this:

button1.Click += DoThis;
button1.Click += ButAlsoThis;

I did this for every button. Then I tried to make a method that removes all methods for a given button. Something like this:

public void RemoveHandlers(Button btn)
{
    //Code to remove handlers
}

That's where I got stuck...

I was hoping C# would accept something like this:

btn.Click = null

But appearantly Events only accept '+=' and '-='.

So now I have this elaborate system where I have buttons and an list of EventHandlers, linked with a dictionairy. Then I remove each Eventhandler individually. It works... But I think there should be an easier way.

So long story short:

Is there an easy method to remove all handlers from an Event without prior knowledge of the handlers involved?

Edit, I found the answer thanks to Carlos Landeras:

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

But I just don't want to copy+paste, I'd like to know what is happening here.

Jordy
  • 1,816
  • 16
  • 29
  • 1
    possible duplicate of [How to remove all event handlers from a control](http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control) – Sergey Berezovskiy Jun 04 '13 at 06:40
  • @lazyberezovsky, thank you! It's amazing how long I search for these thing and other people find it within the minute... I think there is something wrong with my googleskills -.- – Jordy Jun 04 '13 at 06:43

2 Answers2

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

Check this, is exactly what you are looking for:

How to remove all event handlers from a control

Community
  • 1
  • 1
Carlos Landeras
  • 11,025
  • 11
  • 56
  • 82
  • 1
    It is using reflection to get the properties of the control. First it get the type of EventClick into fieldInfo. Then it loads an object with that type from button (b). Then he loads the PropertyInfo looking por Event properties so se can remove the events of that list that were loaded in obj. – Carlos Landeras Jun 04 '13 at 07:01
0
class Program
{
    private event EventHandler demoEvent;

    static void Main(string[] args)
    {
        Program p = new Program();
        p.demoEvent += new EventHandler(Program_DemoEvent);
        var list = p.demoEvent.GetInvocationList();
        var demoEventType = typeof(Program).GetEvent("demoEvent", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        MulticastDelegate myValue = typeof(Program).GetField("demoEvent", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).GetValue(p) as MulticastDelegate;
        var invocationList = myValue.GetInvocationList();
        foreach (var handler in invocationList)
            demoEventType.RemoveEventHandler(p, handler);
    }

    static void Program_DemoEvent(object sender, EventArgs e)
    {

    }
}
Vignesh.N
  • 2,618
  • 2
  • 25
  • 33