vb.net - Remove Event by Name -
i want remove specific handler winforms control visualbasic .net.
for example:
i have windows.forms.toolstripbutton click-event registered save data.
now need remove event button, have no access registerd event-method !! pnly know handle used. in case "click"
for better understanding: have write extension gridview. when multiple lines selected, have integrate mass-editing selected rows. need register new click event savebutton , remove old one. have no acces address of event handler. have button registered event
this tried far:
dim btnsaveeventinfo = btnsave.gettype.getevent("click") dim method = activator.createinstance(btnsaveeventinfo.gettype, true) removehandler btnsave.click, method
this throws invalidcastexception
anyone idea?
gr33tz gangfish
wow. harder nut crack expected. possible this, i'll warn you, it's real mess. ultimately, need delegate
object event. once have that, removing event handler easy because can this:
dim d [delegate] = ' ... (we'll figure out later) each handler [delegate] in d.getinvocationlist() removehandler btnsave.click, directcast(handler, eventhandler) next
however, getting delegate event particularly difficult. reflection makes easy eventinfo
object desired event, not provide simple way delegate event. technically speaking, there no way, sure, delegate, since events encapsulate delegate privately , implemented in custom way. but, since events implemented in "normal" way, possible reflection private delegate hidden in object. of course, of break if microsoft ever decides change "normal" way in compiles events, since that's best option you've got, you're stuck it.
to further complicate things, event handlers winform controls are implemented in custom way (albeit, consistently each other), delegate control's event more complex. there excellent write-up on of on this page of bob powell's blog. it's lengthy me repeat of information here, have used put vb.net example of how solve particular situation:
dim currtype type = btnsave.gettype() dim eventfieldinfo fieldinfo = nothing eventfieldinfo = currtype.getfield("eventclick", bindingflags.static or bindingflags.instance or bindingflags.nonpublic) if eventfieldinfo nothing currtype = currtype.basetype end if loop while eventfieldinfo nothing dim ehl eventhandlerlist = directcast(btnsave.gettype().getproperty("events", bindingflags.instance or bindingflags.nonpublic or bindingflags.flattenhierarchy).getvalue(btnsave), eventhandlerlist) dim d [delegate] = ehl(eventfieldinfo.getvalue(btnsave)) each handler eventhandler in d.getinvocationlist() removehandler btnsave.click, handler next
see link above explanation of why , how works. however, said, quite ugly , break in future versions of .net. therefore, if there other way this, better use alternatives. instance, if have control on code adds event handler, keep separate reference delegate remove later, instance:
dim myclickhandler eventhandler = addressof btnsave_click addhandler btnsave.click, myclickhandler ' ... removehandler btnsave.click, myclickhandler
Comments
Post a Comment