Monday, April 4, 2011

How to remove all event handlers from a control - C# winforms

A few days ago I was stuck in a problem. I was in need of removing certain events from controls that i have on my form. I spend almost 3 hours googling for a suitable code and I found this article http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control in stackoverflow. It helped me alot.

The code I got from there was meant to remove click event from a button. I need to remove double click events from some panels and click events from some buttons. So i made a control extension, which will remove all eventhandlers for a certain event.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
public static class EventExtension
{
    public static void RemoveEvents<T>(this Control target,string Event)
    {

            FieldInfo f1 = typeof(Control).GetField(Event,BindingFlags.Static | BindingFlags.NonPublic);
            object obj = f1.GetValue(target.CastTo<T>());
            PropertyInfo pi =target.CastTo<T>().GetType().GetProperty("Events",
                BindingFlags.NonPublic | BindingFlags.Instance);
            EventHandlerList list = (EventHandlerList)pi.GetValue(target.CastTo<T>(), null);
            list.RemoveHandler(obj, list[obj]);
     

    }

   public static T CastTo<T>(this Object target)
    {
           return (T)target;
    }
}
Now, the usage of this extenstion.

If you need to remove click events from a button,
Button button=new Button();
button.RemoveEvents<Button>("EventClick");
If you need to remove doubleclick events from a panel,
Panel panel=new Panel();
panel.RemoveEvents<Panel>("EventDoubleClick");
Cheers

6 comments:

DadCat said...

Where is CastTo defined?

Anoop M S said...

I have updated the code with the definition for CastTo

Ibrar Mumtaz said...

The above will not work because the Target is not set to an instance so therefore the .CastTo() method will fail and then also the .GetValue() will also fail because 'Target' is not instantiated.

See here: http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control

Answer by: XSL

Let me know otherwise I am wrong, I have tested the code and I am 95% sure that the above code sample is wrong.

Anoop M S said...

I am using this code in one of my application and it works fine.

Panel panel=new Panel();
panel.RemoveEvents("EventDoubleClick");

See here, panel is target and "EventDoubleClick" is event name. Here how can target be null or not instantiated. Please correct me if I am wrong.

Ibrar Mumtaz said...

hmmm, I am working with a PrintDocument object Anoop, and I am tryig to remove the 'PrintPage' event, for me your code does not work?

e.g

PrintDocument _printDoc = new PrintDocument();
_printDoc.PrinterSettings.PrinterName = printerName; ExtensionMethods.RemoveEventHandlersV2(_printDoc, "EventPrintPage");
_printDoc.PrintPage += new PrintPageEventHandler(_printDoc_PrintPage);
_printDoc.Print();

Above you can a simplified version of my code and I tried an alternative attempt but still I get I null exception?

What am I trying to do?
-----------------------

I a PrintDocument object called _printDoc that is supposed to get instantiated once and once only. During the course of the life time my application, many different event handlers may get attached to this '_printDoc' object. To be on the safe side, I remove all event handlers if any and then add a new one to print the document I need printing. Unfortunately, nothing seems to work? Can you try to work something out for me?

: \

Anoop M S said...

Sure, I will test this and let you know, please share your email using my contact page

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More