remove all EventHandlers of a specific Control

回眸只為那壹抹淺笑 提交于 2021-02-18 17:11:17

问题


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 ?


回答1:


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");
}



回答2:


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.




回答3:


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);
}



回答4:


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();
    }

}


来源:https://stackoverflow.com/questions/18773844/remove-all-eventhandlers-of-a-specific-control

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!