473,569 Members | 2,844 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Using reflection to unsubscribe an event

I have a library I'm using that has a lapsed listener issue. I figured I'd
just sneak in and do the unsubscription myself since I don't expect it to be
fixed any time soon.

So, I have the control whose event its subscribed to and it's subscribed to
the VisibleChanged event and has an event handler called
ControlVisibleC hanged.

So basically, what I want to do is:

myControl.Visib leChanged -= new
EventHandler(my Control.Control VisibleChanged) ;

The problem is myControl.Contr olVisibleChange d is private.

So, what do I pass to the EventHandler constructor?

Thanks
Aug 30 '07 #1
10 4361
>The problem is myControl.Contr olVisibleChange d is private.
>
So, what do I pass to the EventHandler constructor?
If you hav the right permissions you can get a MethodInfo for a
private method with Reflection as well. Just make sure you include
BindingFlags.No nPublic when retrieving it.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Aug 31 '07 #2
"Mattias Sjögren" <ma************ ********@mvps.o rgwrote in message
news:%2******** ********@TK2MSF TNGP02.phx.gbl. ..
The problem is myControl.Contr olVisibleChange d is private.

So, what do I pass to the EventHandler constructor?

If you hav the right permissions you can get a MethodInfo for a
private method with Reflection as well. Just make sure you include
BindingFlags.No nPublic when retrieving it.
Mattias
I can get the MethodInfo, but I can't pass the MethodInfo to new
EventHandler() because it doesn't take a method info. It normally takes the
method itself and I certainly need to pass the class instance associated
with the method, somehow.

Aug 31 '07 #3
On Aug 31, 1:33 pm, "pedrito" <pixbypedrito at yahoo.comwrote:
I can get the MethodInfo, but I can't pass the MethodInfo to new
EventHandler() because it doesn't take a method info. It normally takes the
method itself and I certainly need to pass the class instance associated
with the method, somehow.
Is Delegate.Create Delegate what you're after?

Jon

Aug 31 '07 #4

"Jon Skeet [C# MVP]" <sk***@pobox.co mwrote in message
news:11******** **************@ r29g2000hsg.goo glegroups.com.. .
On Aug 31, 1:33 pm, "pedrito" <pixbypedrito at yahoo.comwrote:
>I can get the MethodInfo, but I can't pass the MethodInfo to new
EventHandler () because it doesn't take a method info. It normally takes
the
method itself and I certainly need to pass the class instance associated
with the method, somehow.

Is Delegate.Create Delegate what you're after?

Jon
Jon,

That may just do it. Thanks. I've never actually tried this before, so we'll
see how it goes. Thanks.

Pete
Aug 31 '07 #5
"pedrito" <pixbypedrito at yahoo.comwrote in message
news:ir******** *************** *******@giganew s.com...
>
"Jon Skeet [C# MVP]" <sk***@pobox.co mwrote in message
news:11******** **************@ r29g2000hsg.goo glegroups.com.. .
>On Aug 31, 1:33 pm, "pedrito" <pixbypedrito at yahoo.comwrote:
>>I can get the MethodInfo, but I can't pass the MethodInfo to new
EventHandler( ) because it doesn't take a method info. It normally takes
the
method itself and I certainly need to pass the class instance associated
with the method, somehow.

Is Delegate.Create Delegate what you're after?

Jon

Jon,

That may just do it. Thanks. I've never actually tried this before, so
we'll see how it goes. Thanks.

Pete
Jon,

Not having any luck. This is what I did:

parentControl.V isibleChanged -=
Delegate.Create Delegate(typeof (EventHandler), myControl,
"ControlVisible Changed") as EventHandler;

ControlVisibleC hanged is the event handler. myControl is the control that
subscribed to parentControl.V isibleChanged.

When I do this, I get an ArgumentExcepti on with the message, "Error binding
to target method", which I can only assume is ControlVisibleC hanged because
it's private.

I'm using .NET 1.1, so I don't get the overrides of CreateDelegate that take
a MethodInfo and an object instance, not that it looks like it would matter.
It appears that the exception being thrown is coming from an internal
implementation given that the callstack is:

System.Argument Exception: Error binding to target method.
at System.Delegate .InternalCreate (Object target, String method, Boolean
ignoreCase)
at System.Delegate .CreateDelegate (Type type, Object target, String
method)

and

[MethodImpl(Meth odImplOptions.I nternalCall)]
internal extern void InternalCreate( object target, string method, bool
ignoreCase);

Any idea on how I might around this?

Aug 31 '07 #6
On Aug 31, 2:31 pm, "pedrito" <pixbypedrito at yahoo.comwrote:

<snip>
I'm using .NET 1.1, so I don't get the overrides of CreateDelegate that take
a MethodInfo and an object instance, not that it looks like it would matter.
No, I think that's absolutely what matters. I don't see any reason why
it shouldn't work if you can create the delegate. Unfortunately,
without the right overloads, I'm not sure of the best way of doing
this.

What you *could* do is create a class to encapsulate the method info
and target, and expose a method which has the appropriate signature to
be used as an event handler - that could then call MethodInfo.Invo ke.
It would be relatively slow, but it should work.

Jon

Aug 31 '07 #7

"Jon Skeet [C# MVP]" <sk***@pobox.co mwrote in message
news:11******** **************@ r34g2000hsd.goo glegroups.com.. .
On Aug 31, 2:31 pm, "pedrito" <pixbypedrito at yahoo.comwrote:

<snip>
>I'm using .NET 1.1, so I don't get the overrides of CreateDelegate that
take
a MethodInfo and an object instance, not that it looks like it would
matter.

No, I think that's absolutely what matters. I don't see any reason why
it shouldn't work if you can create the delegate. Unfortunately,
without the right overloads, I'm not sure of the best way of doing
this.

What you *could* do is create a class to encapsulate the method info
and target, and expose a method which has the appropriate signature to
be used as an event handler - that could then call MethodInfo.Invo ke.
It would be relatively slow, but it should work.

Jon
Jon,

You're right. The "Not that it matters" was wrong because the problem is
that it's looking for a public reference.

Here's what I did and I should probably be thrown in jail for doing this,
but it almost seems to have worked.

MethodInfo ovc = typeof(MyContro lClass).GetMeth od("OnVisibleCh anged",
BindingFlags.No nPublic | BindingFlags.In stance);
Delegate ovcDelegate = Delegate.Create Delegate(typeof (EventHandler), this,
"VScrollBarValu eChanged") as EventHandler;

FieldInfo fi = typeof(Delegate ).GetField("_ta rget", BindingFlags.No nPublic |
BindingFlags.In stance);
fi.SetValue(ovc Delegate, myControl);
fi = typeof(Delegate ).GetField("_me thod", BindingFlags.No nPublic |
BindingFlags.In stance);
fi.SetValue(ovc Delegate, ovc);
fi = typeof(Delegate ).GetField("_me thodPtr", BindingFlags.No nPublic |
BindingFlags.In stance);
fi.SetValue(ovc Delegate, ovc.MethodHandl e.Value);
fi = typeof(Delegate ).GetField("_me thodPtrAux", BindingFlags.No nPublic |
BindingFlags.In stance);
fi.SetValue(ovc Delegate, ovc.MethodHandl e.Value);
parentControl.V isibleChanged -= ovcDelegate as EventHandler;

Basically, what I did was I created a dummy delegate that had the same
signature (though I don't think that really matters).

Then, using reflection, I filled in the all the fields of the Delegate with
the information for the event handler I really wanted a delegate for.

Now, as I said, this "almost" worked.

It did appear to successfully remove the old reference. But somehow, it
created an entirely new reference with a call stack leading back to

parentControl.V isibleChanged -= ovcDelegate as EventHandler;

This is according to .NET profiler... The relevant portion of the call stack
is:

MulticastDelega te.RemoveImpl(D elegate)
Delegate.Remove (Delegate, Delegate)
EventHandlerLis t.RemoveHandler (object, Delegate)
Control.remove_ VisibleChanged( EventHandler)

How does that create a reference? Unless it's walking the stack to see where
the call is coming from and saying, "Aha, this is a different class trying
to unsubscribe the original subscription, so let's keep a reference to the
new one..." I don't know. My head is about to pop.

Aug 31 '07 #8
"Jon Skeet [C# MVP]" <sk***@pobox.co mwrote in message
news:11******** **************@ r34g2000hsd.goo glegroups.com.. .
On Aug 31, 2:31 pm, "pedrito" <pixbypedrito at yahoo.comwrote:

<snip>
What you *could* do is create a class to encapsulate the method info
and target, and expose a method which has the appropriate signature to
be used as an event handler - that could then call MethodInfo.Invo ke.
It would be relatively slow, but it should work.
In reference to this, I'm not sure I understand what you mean. Doesn't the
unsubscription need to have the same underlying function pointer (it appears
that's technically how it's happening underneath with the
Delegate._metho dPtr)...

Unless I'm misunderstandin g, your method would unsubscribe a different
_methodPtr...

Aug 31 '07 #9
<"pedrito" <pixbypedrito at yahoo.com>wrote :
What you *could* do is create a class to encapsulate the method info
and target, and expose a method which has the appropriate signature to
be used as an event handler - that could then call MethodInfo.Invo ke.
It would be relatively slow, but it should work.

In reference to this, I'm not sure I understand what you mean. Doesn't the
unsubscription need to have the same underlying function pointer (it appears
that's technically how it's happening underneath with the
Delegate._metho dPtr)...

Unless I'm misunderstandin g, your method would unsubscribe a different
_methodPtr...
You'd have to override Equals in your "extra" class, but then it should
be okay, so long as both subscription and unsubscription were done in
the same manner (i.e. both using the proxy).

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 31 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1540
by: Shawn Hogan | last post by:
Hi everyone, I've been trying to execute a control's private event code via reflection from another class with the goal of potentially doing some unit testing. The examples below are trying to execute button2's click event. This works great when i know the name of the method that i want to invoke. I do so by doing this: Dim...
10
5022
by: Rick Palmer | last post by:
I have an app I'm working on that will allow a user to run one of 5 reports. The report names are in a combobox on my form. I have a sub defined for each report that has the exact same name as is displayed in the combobox. I have one button on the form to start processing. What I want to do is this: When the user selects the report they...
0
2066
by: Kamilche | last post by:
''' event.py An event manager using publish/subscribe, and weakrefs. Any function can publish any event without registering it first, and any object can register interest in any event, even if it doesn't exist yet. The event manager uses weakrefs, so lists of listeners won't stop them
7
1075
by: guy | last post by:
just discovered that the combination of visual inheritance and reflection can eliminate most of the databinding i would normally do, providing the design is right! and its only taken me 4 years lol --guy--
4
6291
by: Douglas Peterson | last post by:
I created the following code: private struct StackItem { public EventHandler theEvent, theHandler; public StackItem(EventHandler theEvent, EventHandler theHandler) { this.theEvent = theEvent; this.theHandler = theHandler; }
2
2650
by: mswlogo | last post by:
I looked high and low for code to do this and finally found some VB code that did it right. This is a C# flavor of it. public event EventHandler<EventArgsMyEventToBeFired; public void FireEvent(Guid instanceId, string handler) { EventArgs e = new EventArgs(instanceId);
2
2746
by: Grzegorz Danowski | last post by:
Hello, I'd like to hide control if any of its event handlers is forbidden for current user (basing on PrincipalPermissionAttribute). How to list all methods that handle given event? I supposed that I should use reflection and I examined EventInfo class but I haven't found in this class any information about handlers list, but there is a...
1
1706
by: John Bode | last post by:
I need a way to fake reflection in C++ code that makes as few assumptions about the data types involved as possible. I suspect there is no good answer for what I need to do, but I'll present the case anyway. We have a class that normally registers with another service, which then executes callbacks in our class. Since that other service...
10
9555
Plater
by: Plater | last post by:
I'm a bit boggled by this since I am rather new to using reflection. I want to attach an event handler via Reflection (which I can do), but I want to NOT have to know the exact event delegate signature. For an exmaple, I have a .DLL with the following: public delegate CustomEnum CustomEventHandler(Socket s, CustomClass c); public class...
0
7695
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7922
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8119
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
6281
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5218
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3653
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3637
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2111
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1209
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.