Http://blog.csdn.net/softman11/article/details/5615267
You may want to delete a previously mounted event when you encounter a dynamic mounting event. If you do not delete the event, it will be mounted again.
Two implementation methods are provided here, which have their respective advantages and disadvantages.
1. Using Reflection Mechanism
Void clearevent (Control, string eventname)
{
If (control = NULL) return;
If (string. isnullorempty (eventname) return;
Bindingflags mpropertyflags = bindingflags. instance | bindingflags. Public | bindingflags. Static | bindingflags. nonpublic;
Bindingflags mfieldflags = bindingflags. Static | bindingflags. nonpublic;
Type controltype = typeof (system. Windows. Forms. control );
Propertyinfo = controltype. getproperty ("Events", mpropertyflags );
Eventhandlerlist = (eventhandlerlist) propertyinfo. getvalue (control, null );
Fieldinfo = (typeof (Control). getfield ("Event" + eventname, mfieldflags );
Delegate d = eventhandlerlist [fieldinfo. getvalue (Control)];
If (D = NULL) return;
Eventinfo = controltype. getevent (eventname );
Foreach (delegate dx in D. getinvocationlist ())
Eventinfo. removeeventhandler (control, dx );
}
Call case:
Clearevent (button1, "click"); // This will clear all hook events of the Click Event of the button1 object.
This method is simple and convenient once and for all. However, reflection mechanisms are introduced. Unless necessary, reflection is not recommended in the program. After all, the compiler cannot check the data types involved in reflection, which may cause instability during program running. Of course, if you are confident enough, there is nothing you can do.
2. Simulates the. Net maintenance event table mechanism and maintains its own event table. In this way, you do not need to introduce reflection. Using a common method can also be easily implemented, and the code is easier to understand.
I recommend this method.
The disadvantage of this method is that you need to define an eventhandlerlist yourself. However, I think it is completely worthwhile to add this point.
First, define a list of stored events. This. Net already provides the eventhandlerlist class. This class storage mechanism is similar to hashmap.
Eventhandlerlist myeventhandlerlist = new eventhandlerlist ();
Then we will write a method for adding events:
Void addevent (Control, eventhandler)
{
Control. Click + = eventhandler;
Myeventhandlerlist. addhandler (control, eventhandler );
}
It is very simple. There are only two lines of code, but this method will be used to add events in the future for deletion in the future. If you do not use this method to add events, they will not be deleted.
You also need to write a method to delete the event:
Void clearevent (Control)
{
Delegate d = myeventhandlerlist [control];
Foreach (delegate DD in D. getinvocationlist ())
Control. Click-= (eventhandler) dd;
Myeventhandlerlist. removehandler (control, d );
}
You can use this method to clear events in the future.
Of course, the problem with this method is how to add and delete events of any method without the reflection mechanism.
In fact, there is no difficulty. Writing a few case statements can solve the problem. Although there are many events, it is not a waste to copy them.
You can also write only the events you care about. Therefore, this will not affect the project.
Conclusion:
Based on the above two methods, design a class to handle such tasks so that they can be called in the future.
Class myeventmanager: idisposable
{
Eventhandlerlist eventlist = new eventhandlerlist ();
Hashtable eventobjectlist = new hashtable ();
Public void addevent (Control, string eventname, eventhandler)
{
String keystr = control. Name + eventname;
If (! Eventobjectlist. Contains (keystr) eventobjectlist. Add (keystr, new object ());
Object eventobject = eventobjectlist [keystr];
Switch (eventname)
{
Case "click ":
Control. Click + = eventhandler;
Break;
Case "enter ":
Control. Enter + = eventhandler;
Break;
//...
// More event support can be added here, because C # does not support macro replacement.
// Of course, reflection can also be used, but reflection does not need to be used.
}
Eventlist. addhandler (eventobject, eventhandler );
}
Public void delevent (Control, string eventname)
{
String keystr = control. Name + eventname;
Object eventobject = eventobjectlist [keystr];
Delegate d = eventlist [eventobject];
If (D = NULL) return;
Foreach (delegate DD in D. getinvocationlist ())
{
Switch (eventname)
{
Case "click ":
Control. Click-= (eventhandler) dd;
Break;
Case "enter ":
Control. Enter-= (eventhandler) dd;
Break;
//...
// More event support can be added here, because C # does not support macro replacement.
// Of course, reflection can also be used, but reflection does not need to be used.
}
}
Eventlist. removehandler (eventobject, d );
Eventobjectlist. Remove (eventobject );
}
Public static void clearevent (Control, string eventname)
{
If (control = NULL) return;
If (string. isnullorempty (eventname) return;
Bindingflags mpropertyflags = bindingflags. instance | bindingflags. Public | bindingflags. Static | bindingflags. nonpublic;
Bindingflags mfieldflags = bindingflags. Static | bindingflags. nonpublic;
Type controltype = typeof (system. Windows. Forms. control );
Propertyinfo = controltype. getproperty ("Events", mpropertyflags );
Eventhandlerlist = (eventhandlerlist) propertyinfo. getvalue (control, null );
Fieldinfo = (typeof (Control). getfield ("Event" + eventname, mfieldflags );
Delegate d = eventhandlerlist [fieldinfo. getvalue (Control)];
If (D = NULL) return;
Eventinfo = controltype. getevent (eventname );
Foreach (delegate dx in D. getinvocationlist ())
Eventinfo. removeeventhandler (control, dx );
}
# Region idisposable members
Public void dispose ()
{
Eventlist. Dispose ();
}
# Endregion
}