3

I'm writing an application in winForm. I have a panel in from1 and it has many event handler. When I dispose panel1 and create new panel , the previous events exist & they fire. For removing panel1 events I have tryed code below.

panel1.Click -=  clickHandle_1 ; 

But it doesn't work every where in program code. for example in another method. How can I remove all previous events of panel1 when I create new panel1 ?

AmirHossein Rezaei
  • 1,086
  • 1
  • 16
  • 20
  • 1
    This is a code smell. You could just write *one* event handler that does the job for all three. Or simply derive a class from Panel that overrides the OnResize and OnClick methods. Nor is it that clear why you'd want to remove them, a bool variable could be checked in the event handler to skip whatever it is doing. Try to post meaningful code instead of this. – Hans Passant Sep 12 '13 at 20:41
  • Agreed. I'd look into applying a variation of the strategy pattern here. http://www.oodesign.com/strategy-pattern.html – dcastro Sep 12 '13 at 20:52

4 Answers4

9

According to this, for cancelling all Click Events of panel1 do this:

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

And for cancelling other events of panel1 change EventClick to event name that you want to remove.

One can get all event names using this code:

EventInfo[] info = type.GetEvents();
for (int i = 0; i < info.Length; i++)
{
   Console.WriteLine(info[i].Name + "\n");
}
AmirHossein Rezaei
  • 1,086
  • 1
  • 16
  • 20
4

Normally when you Dispose an object/control, all the members of that object/control including Event handler list should be disposed too and unusable. So when you say your panel1 is disposed, it's impossible to fire any event on that disposed control (such as Resize). You should check if you surely dispose your panel. Here is a way you can use to remove all the Event handlers of a control using Reflection to Dispose the Events (type of EventHandlerList):

public void RemoveHandlerList(Control c){
  EventHandlerList list = (EventHandlerList) typeof(Control).GetProperty("Events", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(c, null);
  typeof(EventHandlerList).GetMethod("Dispose").Invoke(list, null);
}
King King
  • 61,710
  • 16
  • 105
  • 130
3

Remove them one at a time:

panel1.Click -= clickHandle_1;

There is no clean way of unsubscribing all event handlers at once. Keep track of what you're subscribing and unsubscribe them accordingly.

Ant P
  • 24,820
  • 5
  • 68
  • 105
0

Not sure if this will work but this is closest I came with:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }


    private Dictionary<string, EventHandler> _handlers = new Dictionary<string, EventHandler>();
    TextBox _txt = new TextBox();

    void WireHandlers()
    {

         // get references of your handlers
         EventHandler _hnd1 = delegate { return; }; // here will be your named method. This is only for example
         EventHandler _hnd2 = delegate { return; }; // here will be your named method. This is only for example

         // wire handlers
        _txt.Click += _hnd1;
        _txt.TextChanged  += _hnd2;
         // save wired handler collection
        _handlers.Add("Click", _hnd1);
        _handlers.Add("TextChanged", _hnd2);
    }


    void UnwireHandlers()
    {

        // lets unwire all handlers
        foreach (var kvp in _handlers)
        {
            // inspect keyValuePair - each key corresponds to the name of some event
            switch (kvp.Key)
            {
                case "Click":
                    _txt.Click -= kvp.Value;
                    break;
                case "TextChanged":
                    _txt.TextChanged  -= kvp.Value;
                    break;
                default:
                    throw new Exception("no such handler found");
            }
        }

        _handlers.Clear();
    }

}
T.S.
  • 18,195
  • 11
  • 58
  • 78