问题
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