By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,200 Members | 1,755 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,200 IT Pros & Developers. It's quick & easy.

Matching Event Handlers in an Interface

P: n/a
Mr "yEaH rIgHt" posted the following link about a week ago in answer to my
question about removing event handlers.
http://www.vbinfozine.com/t_bindevt.shtml


Following on from that post, the following issues still exist.

The article shows how to find methods on a receiver that match the pattern
OnXXXX given the sender. It loops through the sender events and tries to get
methods from the receiver that match the pattern. For each one it finds it
either adds or removes a handler for the event.

This is great where there is a straight forward mapping, but I don't have a
straight forward mapping. For example, although I could easily use this
pattern in many cases, there are situations where the sender has two similar
events, only one of which a particular receiver is going to service.

Let's say that my sender has an event ValueChanged. My receiver could easily
have a method OnValueChanged that could be linked up using the technique
above. As it happens, my receiver has a method MyControl_ValueChanged, but
this also works with the technique above.

The problem arises where my sender has two values that can change. In this
case it can raise two events: Value1Changed and Value2Changed. My receiver
only services one of these, and which one is determined at runtime.
Therefore, the receiver still has a method MyControl_ValueChanged, because
it knows nothing of a sender that has two values.

This breaks the pattern, as there is now easy way to transform the event
Value2Changed into the method name MyControl_ValueChanged.

So, ...

I am trying to find a way of looping through the sender's events, as before,
but for each one I want to get the invocation list, and see if my receiver
is in it. Only if it is do I want to remove the handler. I have got this far

<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal receiver
As Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As [Delegate]

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()

' For each event that the sender can raise, get the invocation
list
dlgts = sender.Events.Item( *WHAT GOES
HERE?* ).GetInvocationList()

For Each dlgt As [Delegate] In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt

Next ei

End Sub
</code>

Can someone suggest what might replace the capitalised text? Alternatively,
can
anyone think of another way of achieving the same end?

Thanks.

Charles
Nov 20 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Could someone have a look at this please. It seems to me that it should be
possible to get a list of handlers for an event and then remove any handler
that is in a given object. I just can't figure out how to do it.

Anyone?

Charles
"Charles Law" <bl***@nowhere.com> wrote in message
news:eh**************@TK2MSFTNGP09.phx.gbl...
Mr "yEaH rIgHt" posted the following link about a week ago in answer to my
question about removing event handlers.
http://www.vbinfozine.com/t_bindevt.shtml
Following on from that post, the following issues still exist.

The article shows how to find methods on a receiver that match the pattern
OnXXXX given the sender. It loops through the sender events and tries to

get methods from the receiver that match the pattern. For each one it finds it
either adds or removes a handler for the event.

This is great where there is a straight forward mapping, but I don't have a straight forward mapping. For example, although I could easily use this
pattern in many cases, there are situations where the sender has two similar events, only one of which a particular receiver is going to service.

Let's say that my sender has an event ValueChanged. My receiver could easily have a method OnValueChanged that could be linked up using the technique
above. As it happens, my receiver has a method MyControl_ValueChanged, but
this also works with the technique above.

The problem arises where my sender has two values that can change. In this
case it can raise two events: Value1Changed and Value2Changed. My receiver
only services one of these, and which one is determined at runtime.
Therefore, the receiver still has a method MyControl_ValueChanged, because
it knows nothing of a sender that has two values.

This breaks the pattern, as there is now easy way to transform the event
Value2Changed into the method name MyControl_ValueChanged.

So, ...

I am trying to find a way of looping through the sender's events, as before, but for each one I want to get the invocation list, and see if my receiver
is in it. Only if it is do I want to remove the handler. I have got this far
<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal receiver As Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As [Delegate]

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()

' For each event that the sender can raise, get the invocation
list
dlgts = sender.Events.Item( *WHAT GOES
HERE?* ).GetInvocationList()

For Each dlgt As [Delegate] In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt

Next ei

End Sub
</code>

Can someone suggest what might replace the capitalised text? Alternatively, can
anyone think of another way of achieving the same end?

Thanks.

Charles

Nov 20 '05 #2

P: n/a
Charles,
For Each dlgt As [Delegate] In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
Remember that [Delegate] is short hand for System.Delegate. That
System.Delegate is a class with methods & properties.

I would start by looking at the methods & properties available on the
System.Delegate class.

http://msdn.microsoft.com/library/de...ClassTopic.asp

Specifically the System.Delegate.Target and System.Delegate Method
properties. The System.Delegate.Equals method may or may not help.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:eh**************@TK2MSFTNGP09.phx.gbl... Mr "yEaH rIgHt" posted the following link about a week ago in answer to my
question about removing event handlers.
http://www.vbinfozine.com/t_bindevt.shtml
Following on from that post, the following issues still exist.

The article shows how to find methods on a receiver that match the pattern
OnXXXX given the sender. It loops through the sender events and tries to

get methods from the receiver that match the pattern. For each one it finds it
either adds or removes a handler for the event.

This is great where there is a straight forward mapping, but I don't have a straight forward mapping. For example, although I could easily use this
pattern in many cases, there are situations where the sender has two similar events, only one of which a particular receiver is going to service.

Let's say that my sender has an event ValueChanged. My receiver could easily have a method OnValueChanged that could be linked up using the technique
above. As it happens, my receiver has a method MyControl_ValueChanged, but
this also works with the technique above.

The problem arises where my sender has two values that can change. In this
case it can raise two events: Value1Changed and Value2Changed. My receiver
only services one of these, and which one is determined at runtime.
Therefore, the receiver still has a method MyControl_ValueChanged, because
it knows nothing of a sender that has two values.

This breaks the pattern, as there is now easy way to transform the event
Value2Changed into the method name MyControl_ValueChanged.

So, ...

I am trying to find a way of looping through the sender's events, as before, but for each one I want to get the invocation list, and see if my receiver
is in it. Only if it is do I want to remove the handler. I have got this far
<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal receiver As Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As [Delegate]

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()

' For each event that the sender can raise, get the invocation
list
dlgts = sender.Events.Item( *WHAT GOES
HERE?* ).GetInvocationList()

For Each dlgt As [Delegate] In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt

Next ei

End Sub
</code>

Can someone suggest what might replace the capitalised text? Alternatively, can
anyone think of another way of achieving the same end?

Thanks.

Charles

Nov 20 '05 #3

P: n/a
Hi Jay

Yes, I think that one of those will allow me to test for equality with the
receiver. My first hurdle, though is this line:
dlgts = sender.Events.Item( *WHAT GOES HERE?* ).GetInvocationList()
Given the sender object, I cannot for the life of me see how to drill down
to the invocation list. The Item member seems to need a key in the shape of
an object, but what key should I use? I have searched and searched but
cannot find an example of this anywhere. Can you think what might work?

Thanks.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:Om**************@tk2msftngp13.phx.gbl... Charles,
For Each dlgt As [Delegate] In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
Remember that [Delegate] is short hand for System.Delegate. That
System.Delegate is a class with methods & properties.

I would start by looking at the methods & properties available on the
System.Delegate class.

http://msdn.microsoft.com/library/de...ClassTopic.asp
Specifically the System.Delegate.Target and System.Delegate Method
properties. The System.Delegate.Equals method may or may not help.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:eh**************@TK2MSFTNGP09.phx.gbl...
Mr "yEaH rIgHt" posted the following link about a week ago in answer to my question about removing event handlers.
http://www.vbinfozine.com/t_bindevt.shtml
Following on from that post, the following issues still exist.

The article shows how to find methods on a receiver that match the pattern OnXXXX given the sender. It loops through the sender events and tries to

get
methods from the receiver that match the pattern. For each one it finds it either adds or removes a handler for the event.

This is great where there is a straight forward mapping, but I don't have a
straight forward mapping. For example, although I could easily use this
pattern in many cases, there are situations where the sender has two

similar
events, only one of which a particular receiver is going to service.

Let's say that my sender has an event ValueChanged. My receiver could

easily
have a method OnValueChanged that could be linked up using the technique
above. As it happens, my receiver has a method MyControl_ValueChanged,

but this also works with the technique above.

The problem arises where my sender has two values that can change. In this case it can raise two events: Value1Changed and Value2Changed. My receiver only services one of these, and which one is determined at runtime.
Therefore, the receiver still has a method MyControl_ValueChanged, because it knows nothing of a sender that has two values.

This breaks the pattern, as there is now easy way to transform the event
Value2Changed into the method name MyControl_ValueChanged.

So, ...

I am trying to find a way of looping through the sender's events, as

before,
but for each one I want to get the invocation list, and see if my receiver is in it. Only if it is do I want to remove the handler. I have got this

far

<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal

receiver
As Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As [Delegate]

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()

' For each event that the sender can raise, get the invocation list
dlgts = sender.Events.Item( *WHAT GOES
HERE?* ).GetInvocationList()

For Each dlgt As [Delegate] In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt

Next ei

End Sub
</code>

Can someone suggest what might replace the capitalised text?

Alternatively,
can
anyone think of another way of achieving the same end?

Thanks.

Charles


Nov 20 '05 #4

P: n/a
Charles,
A specific hidden field that the designer of the class supplied when they
added the Event to the HandlerList.

I suspect in your project that sender.Events is nothing, or an empty list.

Generally the class itself will create a key object (via New Object
literally) that is used to index into the Events collection. If you are
using the Events collection you should know what that key is. In that you
would have supplied the key to add the event to the collection.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Hi Jay

Yes, I think that one of those will allow me to test for equality with the
receiver. My first hurdle, though is this line:
dlgts = sender.Events.Item( *WHAT GOES HERE?* ).GetInvocationList()
Given the sender object, I cannot for the life of me see how to drill down
to the invocation list. The Item member seems to need a key in the shape

of an object, but what key should I use? I have searched and searched but
cannot find an example of this anywhere. Can you think what might work?

Thanks.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:Om**************@tk2msftngp13.phx.gbl...
Charles,
For Each dlgt As [Delegate] In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
Remember that [Delegate] is short hand for System.Delegate. That
System.Delegate is a class with methods & properties.

I would start by looking at the methods & properties available on the
System.Delegate class.

http://msdn.microsoft.com/library/de...ClassTopic.asp

Specifically the System.Delegate.Target and System.Delegate Method
properties. The System.Delegate.Equals method may or may not help.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:eh**************@TK2MSFTNGP09.phx.gbl...
Mr "yEaH rIgHt" posted the following link about a week ago in answer to my
question about removing event handlers.

> http://www.vbinfozine.com/t_bindevt.shtml

Following on from that post, the following issues still exist.

The article shows how to find methods on a receiver that match the pattern OnXXXX given the sender. It loops through the sender events and tries
to
get
methods from the receiver that match the pattern. For each one it
finds
it either adds or removes a handler for the event.

This is great where there is a straight forward mapping, but I don't have
a
straight forward mapping. For example, although I could easily use

this pattern in many cases, there are situations where the sender has two

similar
events, only one of which a particular receiver is going to service.

Let's say that my sender has an event ValueChanged. My receiver could

easily
have a method OnValueChanged that could be linked up using the technique above. As it happens, my receiver has a method MyControl_ValueChanged,

but this also works with the technique above.

The problem arises where my sender has two values that can change. In this case it can raise two events: Value1Changed and Value2Changed. My receiver only services one of these, and which one is determined at runtime.
Therefore, the receiver still has a method MyControl_ValueChanged, because it knows nothing of a sender that has two values.

This breaks the pattern, as there is now easy way to transform the event Value2Changed into the method name MyControl_ValueChanged.

So, ...

I am trying to find a way of looping through the sender's events, as

before,
but for each one I want to get the invocation list, and see if my receiver is in it. Only if it is do I want to remove the handler. I have got
this far

<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal

receiver
As Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As [Delegate]

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()

' For each event that the sender can raise, get the

invocation list
dlgts = sender.Events.Item( *WHAT GOES
HERE?* ).GetInvocationList()

For Each dlgt As [Delegate] In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt

Next ei

End Sub
</code>

Can someone suggest what might replace the capitalised text?

Alternatively,
can
anyone think of another way of achieving the same end?

Thanks.

Charles



Nov 20 '05 #5

P: n/a
Jay

I did see once where New Object was used for adding keys, but, as you
suggest that was in a user rolled method.

It seems, from what you are saying, that the invocation list is for user use
only. I had expected that the 'framework' would have a method - that I could
get access to - that allowed me to see all the handlers/delegates to be
called for an event. After all, if this is not the case, how does the
framework do it?

When an event is raised, there must be a list somewhere, of delegates that
will be invoked/called. If I could just get access to/enumerate those
handlers, I would be home and dry.

Incidentally, sender.Events is *not* nothing in my project, and I have only
called AddHandler to add a handler for an event.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2***************@TK2MSFTNGP09.phx.gbl...
Charles,
A specific hidden field that the designer of the class supplied when they
added the Event to the HandlerList.

I suspect in your project that sender.Events is nothing, or an empty list.

Generally the class itself will create a key object (via New Object
literally) that is used to index into the Events collection. If you are
using the Events collection you should know what that key is. In that you
would have supplied the key to add the event to the collection.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Hi Jay

Yes, I think that one of those will allow me to test for equality with the
receiver. My first hurdle, though is this line:
dlgts = sender.Events.Item( *WHAT GOES HERE?* ).GetInvocationList()
Given the sender object, I cannot for the life of me see how to drill down to the invocation list. The Item member seems to need a key in the shape

of
an object, but what key should I use? I have searched and searched but
cannot find an example of this anywhere. Can you think what might work?

Thanks.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:Om**************@tk2msftngp13.phx.gbl...
Charles,
> For Each dlgt As [Delegate] In dlgts
> If *TEST FOR DELEGATE BEING ON RECEIVER?* Then

Remember that [Delegate] is short hand for System.Delegate. That
System.Delegate is a class with methods & properties.

I would start by looking at the methods & properties available on the
System.Delegate class.

http://msdn.microsoft.com/library/de...ClassTopic.asp

Specifically the System.Delegate.Target and System.Delegate Method
properties. The System.Delegate.Equals method may or may not help.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:eh**************@TK2MSFTNGP09.phx.gbl...
> Mr "yEaH rIgHt" posted the following link about a week ago in answer to
my
> question about removing event handlers.
>
> > http://www.vbinfozine.com/t_bindevt.shtml
>
> Following on from that post, the following issues still exist.
>
> The article shows how to find methods on a receiver that match the

pattern
> OnXXXX given the sender. It loops through the sender events and tries to get
> methods from the receiver that match the pattern. For each one it finds
it
> either adds or removes a handler for the event.
>
> This is great where there is a straight forward mapping, but I don't

have
a
> straight forward mapping. For example, although I could easily use this > pattern in many cases, there are situations where the sender has two
similar
> events, only one of which a particular receiver is going to service.
>
> Let's say that my sender has an event ValueChanged. My receiver
could easily
> have a method OnValueChanged that could be linked up using the

technique > above. As it happens, my receiver has a method
MyControl_ValueChanged, but
> this also works with the technique above.
>
> The problem arises where my sender has two values that can change.
In this
> case it can raise two events: Value1Changed and Value2Changed. My

receiver
> only services one of these, and which one is determined at runtime.
> Therefore, the receiver still has a method MyControl_ValueChanged,

because
> it knows nothing of a sender that has two values.
>
> This breaks the pattern, as there is now easy way to transform the

event > Value2Changed into the method name MyControl_ValueChanged.
>
> So, ...
>
> I am trying to find a way of looping through the sender's events, as
before,
> but for each one I want to get the invocation list, and see if my

receiver
> is in it. Only if it is do I want to remove the handler. I have got this far
>
> <code>
> Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal
receiver
> As Object)
>
> Dim SenderType As Type
> Dim ReceiverType As Type
>
> Dim dlgts() As [Delegate]
>
> SenderType = sender.GetType()
> ReceiverType = receiver.GetType()
>
> For Each ei As EventInfo In SenderType.GetEvents()
>
> ' For each event that the sender can raise, get the

invocation
> list
> dlgts = sender.Events.Item( *WHAT GOES
> HERE?* ).GetInvocationList()
>
> For Each dlgt As [Delegate] In dlgts
> If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
> ei.RemoveEventHandler(sender, dlgt)
> End If
> Next dlgt
>
> Next ei
>
> End Sub
> </code>
>
> Can someone suggest what might replace the capitalised text?
Alternatively,
> can
> anyone think of another way of achieving the same end?
>
> Thanks.
>
> Charles
>
>



Nov 20 '05 #6

P: n/a
Charles
sender.Events is totally different then Delegate.GetInvocationList.

Delegate.GetInvocationList is how you see all the handlers to be called for
an event.

sender.Events is all the invocationlists for all the events on a component,
if you designed your component to be used that way. (read its a C# thing).
Incidentally, sender.Events is *not* nothing in my project, and I have only called AddHandler to add a handler for an event. As I stated, I would expect it to be Nothing or an empty list, is it an
empty list?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oz**************@TK2MSFTNGP09.phx.gbl... Jay

I did see once where New Object was used for adding keys, but, as you
suggest that was in a user rolled method.

It seems, from what you are saying, that the invocation list is for user use only. I had expected that the 'framework' would have a method - that I could get access to - that allowed me to see all the handlers/delegates to be
called for an event. After all, if this is not the case, how does the
framework do it?

When an event is raised, there must be a list somewhere, of delegates that
will be invoked/called. If I could just get access to/enumerate those
handlers, I would be home and dry.

Incidentally, sender.Events is *not* nothing in my project, and I have only called AddHandler to add a handler for an event.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2***************@TK2MSFTNGP09.phx.gbl...
Charles,
A specific hidden field that the designer of the class supplied when they
added the Event to the HandlerList.

I suspect in your project that sender.Events is nothing, or an empty list.
Generally the class itself will create a key object (via New Object
literally) that is used to index into the Events collection. If you are
using the Events collection you should know what that key is. In that you would have supplied the key to add the event to the collection.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Hi Jay

Yes, I think that one of those will allow me to test for equality with the receiver. My first hurdle, though is this line:

> dlgts = sender.Events.Item( *WHAT GOES HERE?* ).GetInvocationList()

Given the sender object, I cannot for the life of me see how to drill down to the invocation list. The Item member seems to need a key in the shape of
an object, but what key should I use? I have searched and searched but
cannot find an example of this anywhere. Can you think what might
work?
Thanks.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:Om**************@tk2msftngp13.phx.gbl...
> Charles,
> > For Each dlgt As [Delegate] In dlgts
> > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
>
> Remember that [Delegate] is short hand for System.Delegate. That
> System.Delegate is a class with methods & properties.
>
> I would start by looking at the methods & properties available on the > System.Delegate class.
>
>

http://msdn.microsoft.com/library/de...ClassTopic.asp
>
> Specifically the System.Delegate.Target and System.Delegate Method
> properties. The System.Delegate.Equals method may or may not help.
>
> Hope this helps
> Jay
>
>
> "Charles Law" <bl***@nowhere.com> wrote in message
> news:eh**************@TK2MSFTNGP09.phx.gbl...
> > Mr "yEaH rIgHt" posted the following link about a week ago in answer to
my
> > question about removing event handlers.
> >
> > > http://www.vbinfozine.com/t_bindevt.shtml
> >
> > Following on from that post, the following issues still exist.
> >
> > The article shows how to find methods on a receiver that match the
pattern
> > OnXXXX given the sender. It loops through the sender events and tries
to
> get
> > methods from the receiver that match the pattern. For each one it

finds
it
> > either adds or removes a handler for the event.
> >
> > This is great where there is a straight forward mapping, but I
don't have
> a
> > straight forward mapping. For example, although I could easily use

this
> > pattern in many cases, there are situations where the sender has two > similar
> > events, only one of which a particular receiver is going to service. > >
> > Let's say that my sender has an event ValueChanged. My receiver

could > easily
> > have a method OnValueChanged that could be linked up using the

technique
> > above. As it happens, my receiver has a method MyControl_ValueChanged, but
> > this also works with the technique above.
> >
> > The problem arises where my sender has two values that can change. In this
> > case it can raise two events: Value1Changed and Value2Changed. My
receiver
> > only services one of these, and which one is determined at runtime. > > Therefore, the receiver still has a method MyControl_ValueChanged,
because
> > it knows nothing of a sender that has two values.
> >
> > This breaks the pattern, as there is now easy way to transform the

event
> > Value2Changed into the method name MyControl_ValueChanged.
> >
> > So, ...
> >
> > I am trying to find a way of looping through the sender's events, as > before,
> > but for each one I want to get the invocation list, and see if my
receiver
> > is in it. Only if it is do I want to remove the handler. I have

got this
> far
> >
> > <code>
> > Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal
> receiver
> > As Object)
> >
> > Dim SenderType As Type
> > Dim ReceiverType As Type
> >
> > Dim dlgts() As [Delegate]
> >
> > SenderType = sender.GetType()
> > ReceiverType = receiver.GetType()
> >
> > For Each ei As EventInfo In SenderType.GetEvents()
> >
> > ' For each event that the sender can raise, get the
invocation
> > list
> > dlgts = sender.Events.Item( *WHAT GOES
> > HERE?* ).GetInvocationList()
> >
> > For Each dlgt As [Delegate] In dlgts
> > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
> > ei.RemoveEventHandler(sender, dlgt)
> > End If
> > Next dlgt
> >
> > Next ei
> >
> > End Sub
> > </code>
> >
> > Can someone suggest what might replace the capitalised text?
> Alternatively,
> > can
> > anyone think of another way of achieving the same end?
> >
> > Thanks.
> >
> > Charles
> >
> >
>
>



Nov 20 '05 #7

P: n/a
Jay
sender.Events is totally different then Delegate.GetInvocationList.
I didn't mean to suggest that I thought these were the same. Rather than get
bogged down in (perhaps) my misunderstanding, I will state my aim in PDL

For each event that can be raised by an object (sender)
For each event handler currently attached for the given event
If given event handler is on known target (receiver)
Remove handler
End if
Next event handler
Next event

I don't know how to state it any better than that.
As I stated, I would expect it to be Nothing or an empty list, is it an
empty list?
I can't tell if it is an empty list because there is no member for
retrieving the length, and none for indexing either.

Thanks for your continued help.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:u1***************@tk2msftngp13.phx.gbl... Charles
sender.Events is totally different then Delegate.GetInvocationList.

Delegate.GetInvocationList is how you see all the handlers to be called for an event.

sender.Events is all the invocationlists for all the events on a component, if you designed your component to be used that way. (read its a C# thing).
Incidentally, sender.Events is *not* nothing in my project, and I have only
called AddHandler to add a handler for an event.

As I stated, I would expect it to be Nothing or an empty list, is it an
empty list?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oz**************@TK2MSFTNGP09.phx.gbl...
Jay

I did see once where New Object was used for adding keys, but, as you
suggest that was in a user rolled method.

It seems, from what you are saying, that the invocation list is for user

use
only. I had expected that the 'framework' would have a method - that I

could
get access to - that allowed me to see all the handlers/delegates to be
called for an event. After all, if this is not the case, how does the
framework do it?

When an event is raised, there must be a list somewhere, of delegates that
will be invoked/called. If I could just get access to/enumerate those
handlers, I would be home and dry.

Incidentally, sender.Events is *not* nothing in my project, and I have

only
called AddHandler to add a handler for an event.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:%2***************@TK2MSFTNGP09.phx.gbl...
Charles,
A specific hidden field that the designer of the class supplied when they added the Event to the HandlerList.

I suspect in your project that sender.Events is nothing, or an empty list.
Generally the class itself will create a key object (via New Object
literally) that is used to index into the Events collection. If you are using the Events collection you should know what that key is. In that you would have supplied the key to add the event to the collection.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
> Hi Jay
>
> Yes, I think that one of those will allow me to test for equality with the
> receiver. My first hurdle, though is this line:
>
> > dlgts = sender.Events.Item( *WHAT GOES
HERE?* ).GetInvocationList() >
> Given the sender object, I cannot for the life of me see how to drill
down
> to the invocation list. The Item member seems to need a key in the shape of
> an object, but what key should I use? I have searched and searched
but > cannot find an example of this anywhere. Can you think what might

work? >
> Thanks.
>
> Charles
>
>
> "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message
> news:Om**************@tk2msftngp13.phx.gbl...
> > Charles,
> > > For Each dlgt As [Delegate] In dlgts
> > > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
> >
> > Remember that [Delegate] is short hand for System.Delegate. That
> > System.Delegate is a class with methods & properties.
> >
> > I would start by looking at the methods & properties available on the > > System.Delegate class.
> >
> >
>

http://msdn.microsoft.com/library/de...ClassTopic.asp
> >
> > Specifically the System.Delegate.Target and System.Delegate Method
> > properties. The System.Delegate.Equals method may or may not help.
> >
> > Hope this helps
> > Jay
> >
> >
> > "Charles Law" <bl***@nowhere.com> wrote in message
> > news:eh**************@TK2MSFTNGP09.phx.gbl...
> > > Mr "yEaH rIgHt" posted the following link about a week ago in answer to
> my
> > > question about removing event handlers.
> > >
> > > > http://www.vbinfozine.com/t_bindevt.shtml
> > >
> > > Following on from that post, the following issues still exist.
> > >
> > > The article shows how to find methods on a receiver that match the > pattern
> > > OnXXXX given the sender. It loops through the sender events and

tries
to
> > get
> > > methods from the receiver that match the pattern. For each one it finds
> it
> > > either adds or removes a handler for the event.
> > >
> > > This is great where there is a straight forward mapping, but I don't > have
> > a
> > > straight forward mapping. For example, although I could easily use this
> > > pattern in many cases, there are situations where the sender has two > > similar
> > > events, only one of which a particular receiver is going to service. > > >
> > > Let's say that my sender has an event ValueChanged. My receiver

could
> > easily
> > > have a method OnValueChanged that could be linked up using the
technique
> > > above. As it happens, my receiver has a method

MyControl_ValueChanged,
> but
> > > this also works with the technique above.
> > >
> > > The problem arises where my sender has two values that can change. In
> this
> > > case it can raise two events: Value1Changed and Value2Changed.
My > receiver
> > > only services one of these, and which one is determined at

runtime. > > > Therefore, the receiver still has a method MyControl_ValueChanged, > because
> > > it knows nothing of a sender that has two values.
> > >
> > > This breaks the pattern, as there is now easy way to transform the event
> > > Value2Changed into the method name MyControl_ValueChanged.
> > >
> > > So, ...
> > >
> > > I am trying to find a way of looping through the sender's events, as
> > before,
> > > but for each one I want to get the invocation list, and see if
my > receiver
> > > is in it. Only if it is do I want to remove the handler. I have

got this
> > far
> > >
> > > <code>
> > > Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal > > receiver
> > > As Object)
> > >
> > > Dim SenderType As Type
> > > Dim ReceiverType As Type
> > >
> > > Dim dlgts() As [Delegate]
> > >
> > > SenderType = sender.GetType()
> > > ReceiverType = receiver.GetType()
> > >
> > > For Each ei As EventInfo In SenderType.GetEvents()
> > >
> > > ' For each event that the sender can raise, get the
> invocation
> > > list
> > > dlgts = sender.Events.Item( *WHAT GOES
> > > HERE?* ).GetInvocationList()
> > >
> > > For Each dlgt As [Delegate] In dlgts
> > > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
> > > ei.RemoveEventHandler(sender, dlgt)
> > > End If
> > > Next dlgt
> > >
> > > Next ei
> > >
> > > End Sub
> > > </code>
> > >
> > > Can someone suggest what might replace the capitalised text?
> > Alternatively,
> > > can
> > > anyone think of another way of achieving the same end?
> > >
> > > Thanks.
> > >
> > > Charles
> > >
> > >
> >
> >
>
>



Nov 20 '05 #8

P: n/a
Charles,
I didn't mean to suggest that I thought these were the same. Rather than get bogged down in (perhaps) my misunderstanding, I will state my aim in PDL

For each event that can be raised by an object (sender) Unfortunately I believe you will need to enable the "Option Psychic On"
option, As sender.Events is a secure door, you can only get out what you
know you put in. Which is part of the entire point behind Encapsulation. The
object protects the information that it knows, you need to ask the object
itself for details, if it decides those details are too important not to
share, well its protecting your from yourself...

As I stated, I would expect it to be Nothing or an empty list, is it an
empty list?


I can't tell if it is an empty list because there is no member for
retrieving the length, and none for indexing either.

I thought I saw that EventHandlerList implemented IEnumerable, you are
correct it doesn't, so obviously you cannot use it for what you want.
Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:ea**************@TK2MSFTNGP10.phx.gbl... Jay
sender.Events is totally different then Delegate.GetInvocationList.
I didn't mean to suggest that I thought these were the same. Rather than

get bogged down in (perhaps) my misunderstanding, I will state my aim in PDL

For each event that can be raised by an object (sender)
For each event handler currently attached for the given event
If given event handler is on known target (receiver)
Remove handler
End if
Next event handler
Next event

I don't know how to state it any better than that.
As I stated, I would expect it to be Nothing or an empty list, is it an
empty list?


I can't tell if it is an empty list because there is no member for
retrieving the length, and none for indexing either.

Thanks for your continued help.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:u1***************@tk2msftngp13.phx.gbl...
Charles
sender.Events is totally different then Delegate.GetInvocationList.

Delegate.GetInvocationList is how you see all the handlers to be called

for
an event.

sender.Events is all the invocationlists for all the events on a

component,
if you designed your component to be used that way. (read its a C# thing).
Incidentally, sender.Events is *not* nothing in my project, and I have

only
called AddHandler to add a handler for an event.

As I stated, I would expect it to be Nothing or an empty list, is it an
empty list?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oz**************@TK2MSFTNGP09.phx.gbl...
Jay

I did see once where New Object was used for adding keys, but, as you
suggest that was in a user rolled method.

It seems, from what you are saying, that the invocation list is for user
use
only. I had expected that the 'framework' would have a method - that I

could
get access to - that allowed me to see all the handlers/delegates to
be called for an event. After all, if this is not the case, how does the
framework do it?

When an event is raised, there must be a list somewhere, of delegates

that will be invoked/called. If I could just get access to/enumerate those
handlers, I would be home and dry.

Incidentally, sender.Events is *not* nothing in my project, and I have

only
called AddHandler to add a handler for an event.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:%2***************@TK2MSFTNGP09.phx.gbl...
> Charles,
> A specific hidden field that the designer of the class supplied when

they
> added the Event to the HandlerList.
>
> I suspect in your project that sender.Events is nothing, or an empty

list.
>
> Generally the class itself will create a key object (via New Object
> literally) that is used to index into the Events collection. If you are > using the Events collection you should know what that key is. In that you
> would have supplied the key to add the event to the collection.
>
> Hope this helps
> Jay
>
>
> "Charles Law" <bl***@nowhere.com> wrote in message
> news:%2****************@TK2MSFTNGP10.phx.gbl...
> > Hi Jay
> >
> > Yes, I think that one of those will allow me to test for equality with the
> > receiver. My first hurdle, though is this line:
> >
> > > dlgts = sender.Events.Item( *WHAT GOES HERE?* ).GetInvocationList() > >
> > Given the sender object, I cannot for the life of me see how to drill down
> > to the invocation list. The Item member seems to need a key in the

shape
> of
> > an object, but what key should I use? I have searched and searched but > > cannot find an example of this anywhere. Can you think what might

work?
> >
> > Thanks.
> >
> > Charles
> >
> >
> > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in
message
> > news:Om**************@tk2msftngp13.phx.gbl...
> > > Charles,
> > > > For Each dlgt As [Delegate] In dlgts
> > > > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
> > >
> > > Remember that [Delegate] is short hand for System.Delegate. That
> > > System.Delegate is a class with methods & properties.
> > >
> > > I would start by looking at the methods & properties available
on
the
> > > System.Delegate class.
> > >
> > >
> >
>

http://msdn.microsoft.com/library/de...ClassTopic.asp > > >
> > > Specifically the System.Delegate.Target and System.Delegate Method > > > properties. The System.Delegate.Equals method may or may not help. > > >
> > > Hope this helps
> > > Jay
> > >
> > >
> > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > news:eh**************@TK2MSFTNGP09.phx.gbl...
> > > > Mr "yEaH rIgHt" posted the following link about a week ago in

answer
> to
> > my
> > > > question about removing event handlers.
> > > >
> > > > > http://www.vbinfozine.com/t_bindevt.shtml
> > > >
> > > > Following on from that post, the following issues still exist.
> > > >
> > > > The article shows how to find methods on a receiver that match the > > pattern
> > > > OnXXXX given the sender. It loops through the sender events and tries
> to
> > > get
> > > > methods from the receiver that match the pattern. For each one it > finds
> > it
> > > > either adds or removes a handler for the event.
> > > >
> > > > This is great where there is a straight forward mapping, but I

don't
> > have
> > > a
> > > > straight forward mapping. For example, although I could easily use > this
> > > > pattern in many cases, there are situations where the sender has two
> > > similar
> > > > events, only one of which a particular receiver is going to

service.
> > > >
> > > > Let's say that my sender has an event ValueChanged. My
receiver could
> > > easily
> > > > have a method OnValueChanged that could be linked up using the
> technique
> > > > above. As it happens, my receiver has a method
MyControl_ValueChanged,
> > but
> > > > this also works with the technique above.
> > > >
> > > > The problem arises where my sender has two values that can change. In
> > this
> > > > case it can raise two events: Value1Changed and Value2Changed. My > > receiver
> > > > only services one of these, and which one is determined at

runtime.
> > > > Therefore, the receiver still has a method MyControl_ValueChanged, > > because
> > > > it knows nothing of a sender that has two values.
> > > >
> > > > This breaks the pattern, as there is now easy way to transform the > event
> > > > Value2Changed into the method name MyControl_ValueChanged.
> > > >
> > > > So, ...
> > > >
> > > > I am trying to find a way of looping through the sender's events,
as
> > > before,
> > > > but for each one I want to get the invocation list, and see if

my > > receiver
> > > > is in it. Only if it is do I want to remove the handler. I have got
> this
> > > far
> > > >
> > > > <code>
> > > > Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal > > > receiver
> > > > As Object)
> > > >
> > > > Dim SenderType As Type
> > > > Dim ReceiverType As Type
> > > >
> > > > Dim dlgts() As [Delegate]
> > > >
> > > > SenderType = sender.GetType()
> > > > ReceiverType = receiver.GetType()
> > > >
> > > > For Each ei As EventInfo In SenderType.GetEvents()
> > > >
> > > > ' For each event that the sender can raise, get

the > > invocation
> > > > list
> > > > dlgts = sender.Events.Item( *WHAT GOES
> > > > HERE?* ).GetInvocationList()
> > > >
> > > > For Each dlgt As [Delegate] In dlgts
> > > > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
> > > > ei.RemoveEventHandler(sender, dlgt)
> > > > End If
> > > > Next dlgt
> > > >
> > > > Next ei
> > > >
> > > > End Sub
> > > > </code>
> > > >
> > > > Can someone suggest what might replace the capitalised text?
> > > Alternatively,
> > > > can
> > > > anyone think of another way of achieving the same end?
> > > >
> > > > Thanks.
> > > >
> > > > Charles
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 20 '05 #9

P: n/a
Jay

Perhaps we can approach this in another way. I have repeated my original
code below. If I don't use sender.Events - as you have explained why - is
there a way to create a delegate from ei (an EventInfo object)?

If I could create such a delegate (dlgt) , then I could use
dlgt.GetInvocationList() instead, and I would be well on my way.

What do you think?

Charles

<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal receiver As
Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As System.Delegate

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()
' For each event that the sender can raise, get the invocation list
dlgts = sender.Events.Item( *WHAT GOES HERE?* ).GetInvocationList()

For Each dlgt As System.Delegate In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt
Next ei

End Sub
</code>
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:et**************@TK2MSFTNGP10.phx.gbl...
Charles,
I didn't mean to suggest that I thought these were the same. Rather than get
bogged down in (perhaps) my misunderstanding, I will state my aim in PDL

For each event that can be raised by an object (sender)

Unfortunately I believe you will need to enable the "Option Psychic On"
option, As sender.Events is a secure door, you can only get out what you
know you put in. Which is part of the entire point behind Encapsulation.

The object protects the information that it knows, you need to ask the object
itself for details, if it decides those details are too important not to
share, well its protecting your from yourself...

As I stated, I would expect it to be Nothing or an empty list, is it an empty list?


I can't tell if it is an empty list because there is no member for
retrieving the length, and none for indexing either.

I thought I saw that EventHandlerList implemented IEnumerable, you are
correct it doesn't, so obviously you cannot use it for what you want.
Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:ea**************@TK2MSFTNGP10.phx.gbl...
Jay
sender.Events is totally different then Delegate.GetInvocationList.


I didn't mean to suggest that I thought these were the same. Rather than

get
bogged down in (perhaps) my misunderstanding, I will state my aim in PDL

For each event that can be raised by an object (sender)
For each event handler currently attached for the given event
If given event handler is on known target (receiver)
Remove handler
End if
Next event handler
Next event

I don't know how to state it any better than that.
As I stated, I would expect it to be Nothing or an empty list, is it an empty list?


I can't tell if it is an empty list because there is no member for
retrieving the length, and none for indexing either.

Thanks for your continued help.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:u1***************@tk2msftngp13.phx.gbl...
Charles
sender.Events is totally different then Delegate.GetInvocationList.

Delegate.GetInvocationList is how you see all the handlers to be called
for
an event.

sender.Events is all the invocationlists for all the events on a

component,
if you designed your component to be used that way. (read its a C# thing).
> Incidentally, sender.Events is *not* nothing in my project, and I
have only
> called AddHandler to add a handler for an event.
As I stated, I would expect it to be Nothing or an empty list, is it an empty list?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oz**************@TK2MSFTNGP09.phx.gbl...
> Jay
>
> I did see once where New Object was used for adding keys, but, as you > suggest that was in a user rolled method.
>
> It seems, from what you are saying, that the invocation list is for

user use
> only. I had expected that the 'framework' would have a method - that I could
> get access to - that allowed me to see all the handlers/delegates to be > called for an event. After all, if this is not the case, how does the > framework do it?
>
> When an event is raised, there must be a list somewhere, of delegates that
> will be invoked/called. If I could just get access to/enumerate
those > handlers, I would be home and dry.
>
> Incidentally, sender.Events is *not* nothing in my project, and I have only
> called AddHandler to add a handler for an event.
>
> Charles
>
>
> "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message
> news:%2***************@TK2MSFTNGP09.phx.gbl...
> > Charles,
> > A specific hidden field that the designer of the class supplied when they
> > added the Event to the HandlerList.
> >
> > I suspect in your project that sender.Events is nothing, or an empty list.
> >
> > Generally the class itself will create a key object (via New Object > > literally) that is used to index into the Events collection. If you
are
> > using the Events collection you should know what that key is. In that you
> > would have supplied the key to add the event to the collection.
> >
> > Hope this helps
> > Jay
> >
> >
> > "Charles Law" <bl***@nowhere.com> wrote in message
> > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > Hi Jay
> > >
> > > Yes, I think that one of those will allow me to test for
equality with
> the
> > > receiver. My first hurdle, though is this line:
> > >
> > > > dlgts = sender.Events.Item( *WHAT GOES

HERE?* ).GetInvocationList()
> > >
> > > Given the sender object, I cannot for the life of me see how to

drill
> down
> > > to the invocation list. The Item member seems to need a key in
the shape
> > of
> > > an object, but what key should I use? I have searched and searched but
> > > cannot find an example of this anywhere. Can you think what
might work?
> > >
> > > Thanks.
> > >
> > > Charles
> > >
> > >
> > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in > message
> > > news:Om**************@tk2msftngp13.phx.gbl...
> > > > Charles,
> > > > > For Each dlgt As [Delegate] In dlgts
> > > > > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then > > > >
> > > > Remember that [Delegate] is short hand for System.Delegate. That > > > > System.Delegate is a class with methods & properties.
> > > >
> > > > I would start by looking at the methods & properties available

on the
> > > > System.Delegate class.
> > > >
> > > >
> > >
> >
>

http://msdn.microsoft.com/library/de...ClassTopic.asp
> > > >
> > > > Specifically the System.Delegate.Target and System.Delegate Method > > > > properties. The System.Delegate.Equals method may or may not help. > > > >
> > > > Hope this helps
> > > > Jay
> > > >
> > > >
> > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > news:eh**************@TK2MSFTNGP09.phx.gbl...
> > > > > Mr "yEaH rIgHt" posted the following link about a week ago in answer
> > to
> > > my
> > > > > question about removing event handlers.
> > > > >
> > > > > > http://www.vbinfozine.com/t_bindevt.shtml
> > > > >
> > > > > Following on from that post, the following issues still exist. > > > > >
> > > > > The article shows how to find methods on a receiver that match the
> > > pattern
> > > > > OnXXXX given the sender. It loops through the sender events and > tries
> > to
> > > > get
> > > > > methods from the receiver that match the pattern. For each
one
it
> > finds
> > > it
> > > > > either adds or removes a handler for the event.
> > > > >
> > > > > This is great where there is a straight forward mapping, but
I don't
> > > have
> > > > a
> > > > > straight forward mapping. For example, although I could easily use
> > this
> > > > > pattern in many cases, there are situations where the sender has two
> > > > similar
> > > > > events, only one of which a particular receiver is going to
service.
> > > > >
> > > > > Let's say that my sender has an event ValueChanged. My receiver > could
> > > > easily
> > > > > have a method OnValueChanged that could be linked up using
the > > technique
> > > > > above. As it happens, my receiver has a method
> MyControl_ValueChanged,
> > > but
> > > > > this also works with the technique above.
> > > > >
> > > > > The problem arises where my sender has two values that can

change.
> In
> > > this
> > > > > case it can raise two events: Value1Changed and Value2Changed. My
> > > receiver
> > > > > only services one of these, and which one is determined at
runtime.
> > > > > Therefore, the receiver still has a method

MyControl_ValueChanged,
> > > because
> > > > > it knows nothing of a sender that has two values.
> > > > >
> > > > > This breaks the pattern, as there is now easy way to
transform the
> > event
> > > > > Value2Changed into the method name MyControl_ValueChanged.
> > > > >
> > > > > So, ...
> > > > >
> > > > > I am trying to find a way of looping through the sender's

events,
as
> > > > before,
> > > > > but for each one I want to get the invocation list, and see
if my
> > > receiver
> > > > > is in it. Only if it is do I want to remove the handler. I

have got
> > this
> > > > far
> > > > >
> > > > > <code>
> > > > > Public Shared Sub RemoveHandlers(ByVal sender As Object,

ByVal
> > > > receiver
> > > > > As Object)
> > > > >
> > > > > Dim SenderType As Type
> > > > > Dim ReceiverType As Type
> > > > >
> > > > > Dim dlgts() As [Delegate]
> > > > >
> > > > > SenderType = sender.GetType()
> > > > > ReceiverType = receiver.GetType()
> > > > >
> > > > > For Each ei As EventInfo In SenderType.GetEvents()
> > > > >
> > > > > ' For each event that the sender can raise, get the > > > invocation
> > > > > list
> > > > > dlgts = sender.Events.Item( *WHAT GOES
> > > > > HERE?* ).GetInvocationList()
> > > > >
> > > > > For Each dlgt As [Delegate] In dlgts
> > > > > If *TEST FOR DELEGATE BEING ON RECEIVER?*

Then > > > > > ei.RemoveEventHandler(sender, dlgt)
> > > > > End If
> > > > > Next dlgt
> > > > >
> > > > > Next ei
> > > > >
> > > > > End Sub
> > > > > </code>
> > > > >
> > > > > Can someone suggest what might replace the capitalised text? > > > > Alternatively,
> > > > > can
> > > > > anyone think of another way of achieving the same end?
> > > > >
> > > > > Thanks.
> > > > >
> > > > > Charles
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 20 '05 #10

P: n/a
Charles,
You would need to get at the underlying field that is used as the backing
store for the Event. Or know the magic key to the Events property.

Remember that an Event simply encapsulates a Delegate Field, similar to how
a Property encapsulates other fields.

For example in VB.NET the Changed Event has a ChangeEvent delegate field on
the class.

Just as a Property does not need to be implemented in terms of an actual
field, an Event (in C#) does not need to be implemented in terms of a
Delegate Field. In C# the delegates can be stored in the Events property (an
EventHandlerList class). VB.NET currently does not support the Events
property.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:uC**************@tk2msftngp13.phx.gbl...
Jay

Perhaps we can approach this in another way. I have repeated my original
code below. If I don't use sender.Events - as you have explained why - is
there a way to create a delegate from ei (an EventInfo object)?

If I could create such a delegate (dlgt) , then I could use
dlgt.GetInvocationList() instead, and I would be well on my way.

What do you think?

Charles

<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal receiver As
Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As System.Delegate

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()
' For each event that the sender can raise, get the invocation list dlgts = sender.Events.Item( *WHAT GOES HERE?* ).GetInvocationList()
For Each dlgt As System.Delegate In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt
Next ei

End Sub
</code>
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:et**************@TK2MSFTNGP10.phx.gbl...
Charles,
I didn't mean to suggest that I thought these were the same. Rather than
get
bogged down in (perhaps) my misunderstanding, I will state my aim in
PDL
For each event that can be raised by an object (sender) Unfortunately I believe you will need to enable the "Option Psychic On"
option, As sender.Events is a secure door, you can only get out what you
know you put in. Which is part of the entire point behind Encapsulation.

The
object protects the information that it knows, you need to ask the object itself for details, if it decides those details are too important not to
share, well its protecting your from yourself...

> As I stated, I would expect it to be Nothing or an empty list, is it an > empty list?

I can't tell if it is an empty list because there is no member for
retrieving the length, and none for indexing either.

I thought I saw that EventHandlerList implemented IEnumerable, you are
correct it doesn't, so obviously you cannot use it for what you want.
Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:ea**************@TK2MSFTNGP10.phx.gbl...
Jay

> sender.Events is totally different then Delegate.GetInvocationList.

I didn't mean to suggest that I thought these were the same. Rather than get
bogged down in (perhaps) my misunderstanding, I will state my aim in
PDL
For each event that can be raised by an object (sender)
For each event handler currently attached for the given event
If given event handler is on known target (receiver)
Remove handler
End if
Next event handler
Next event

I don't know how to state it any better than that.

> As I stated, I would expect it to be Nothing or an empty list, is it an > empty list?

I can't tell if it is an empty list because there is no member for
retrieving the length, and none for indexing either.

Thanks for your continued help.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:u1***************@tk2msftngp13.phx.gbl...
> Charles
> sender.Events is totally different then Delegate.GetInvocationList.
>
> Delegate.GetInvocationList is how you see all the handlers to be called for
> an event.
>
> sender.Events is all the invocationlists for all the events on a
component,
> if you designed your component to be used that way. (read its a C#

thing).
>
> > Incidentally, sender.Events is *not* nothing in my project, and I have > only
> > called AddHandler to add a handler for an event.
> As I stated, I would expect it to be Nothing or an empty list, is it an > empty list?
>
> Hope this helps
> Jay
>
> "Charles Law" <bl***@nowhere.com> wrote in message
> news:Oz**************@TK2MSFTNGP09.phx.gbl...
> > Jay
> >
> > I did see once where New Object was used for adding keys, but, as you > > suggest that was in a user rolled method.
> >
> > It seems, from what you are saying, that the invocation list is for user
> use
> > only. I had expected that the 'framework' would have a method -
that I > could
> > get access to - that allowed me to see all the handlers/delegates
to
be
> > called for an event. After all, if this is not the case, how does the > > framework do it?
> >
> > When an event is raised, there must be a list somewhere, of delegates that
> > will be invoked/called. If I could just get access to/enumerate those > > handlers, I would be home and dry.
> >
> > Incidentally, sender.Events is *not* nothing in my project, and I have > only
> > called AddHandler to add a handler for an event.
> >
> > Charles
> >
> >
> > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in
message
> > news:%2***************@TK2MSFTNGP09.phx.gbl...
> > > Charles,
> > > A specific hidden field that the designer of the class supplied when > they
> > > added the Event to the HandlerList.
> > >
> > > I suspect in your project that sender.Events is nothing, or an empty > list.
> > >
> > > Generally the class itself will create a key object (via New Object > > > literally) that is used to index into the Events collection. If you are
> > > using the Events collection you should know what that key is. In that
> you
> > > would have supplied the key to add the event to the collection.
> > >
> > > Hope this helps
> > > Jay
> > >
> > >
> > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > > Hi Jay
> > > >
> > > > Yes, I think that one of those will allow me to test for equality with
> > the
> > > > receiver. My first hurdle, though is this line:
> > > >
> > > > > dlgts = sender.Events.Item( *WHAT GOES
HERE?* ).GetInvocationList()
> > > >
> > > > Given the sender object, I cannot for the life of me see how
to drill
> > down
> > > > to the invocation list. The Item member seems to need a key in

the > shape
> > > of
> > > > an object, but what key should I use? I have searched and searched but
> > > > cannot find an example of this anywhere. Can you think what might > work?
> > > >
> > > > Thanks.
> > > >
> > > > Charles
> > > >
> > > >
> > > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in > > message
> > > > news:Om**************@tk2msftngp13.phx.gbl...
> > > > > Charles,
> > > > > > For Each dlgt As [Delegate] In dlgts
> > > > > > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then > > > > >
> > > > > Remember that [Delegate] is short hand for System.Delegate. That > > > > > System.Delegate is a class with methods & properties.
> > > > >
> > > > > I would start by looking at the methods & properties available on
> the
> > > > > System.Delegate class.
> > > > >
> > > > >
> > > >
> > >
> >
>

http://msdn.microsoft.com/library/de...ClassTopic.asp > > > > >
> > > > > Specifically the System.Delegate.Target and System.Delegate

Method
> > > > > properties. The System.Delegate.Equals method may or may not

help.
> > > > >
> > > > > Hope this helps
> > > > > Jay
> > > > >
> > > > >
> > > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > > news:eh**************@TK2MSFTNGP09.phx.gbl...
> > > > > > Mr "yEaH rIgHt" posted the following link about a week ago in > answer
> > > to
> > > > my
> > > > > > question about removing event handlers.
> > > > > >
> > > > > > > http://www.vbinfozine.com/t_bindevt.shtml
> > > > > >
> > > > > > Following on from that post, the following issues still exist. > > > > > >
> > > > > > The article shows how to find methods on a receiver that match the
> > > > pattern
> > > > > > OnXXXX given the sender. It loops through the sender events
and
> > tries
> > > to
> > > > > get
> > > > > > methods from the receiver that match the pattern. For each one it
> > > finds
> > > > it
> > > > > > either adds or removes a handler for the event.
> > > > > >
> > > > > > This is great where there is a straight forward mapping,
but I > don't
> > > > have
> > > > > a
> > > > > > straight forward mapping. For example, although I could easily use
> > > this
> > > > > > pattern in many cases, there are situations where the
sender
has
> two
> > > > > similar
> > > > > > events, only one of which a particular receiver is going
to > service.
> > > > > >
> > > > > > Let's say that my sender has an event ValueChanged. My receiver
> > could
> > > > > easily
> > > > > > have a method OnValueChanged that could be linked up using

the > > > technique
> > > > > > above. As it happens, my receiver has a method
> > MyControl_ValueChanged,
> > > > but
> > > > > > this also works with the technique above.
> > > > > >
> > > > > > The problem arises where my sender has two values that can
change.
> > In
> > > > this
> > > > > > case it can raise two events: Value1Changed and Value2Changed. My
> > > > receiver
> > > > > > only services one of these, and which one is determined at
> runtime.
> > > > > > Therefore, the receiver still has a method
MyControl_ValueChanged,
> > > > because
> > > > > > it knows nothing of a sender that has two values.
> > > > > >
> > > > > > This breaks the pattern, as there is now easy way to transform the
> > > event
> > > > > > Value2Changed into the method name MyControl_ValueChanged.
> > > > > >
> > > > > > So, ...
> > > > > >
> > > > > > I am trying to find a way of looping through the sender's
events,
> as
> > > > > before,
> > > > > > but for each one I want to get the invocation list, and see if
my
> > > > receiver
> > > > > > is in it. Only if it is do I want to remove the handler. I

have
> got
> > > this
> > > > > far
> > > > > >
> > > > > > <code>
> > > > > > Public Shared Sub RemoveHandlers(ByVal sender As
Object, ByVal
> > > > > receiver
> > > > > > As Object)
> > > > > >
> > > > > > Dim SenderType As Type
> > > > > > Dim ReceiverType As Type
> > > > > >
> > > > > > Dim dlgts() As [Delegate]
> > > > > >
> > > > > > SenderType = sender.GetType()
> > > > > > ReceiverType = receiver.GetType()
> > > > > >
> > > > > > For Each ei As EventInfo In SenderType.GetEvents()
> > > > > >
> > > > > > ' For each event that the sender can raise,

get the
> > > > invocation
> > > > > > list
> > > > > > dlgts = sender.Events.Item( *WHAT GOES
> > > > > > HERE?* ).GetInvocationList()
> > > > > >
> > > > > > For Each dlgt As [Delegate] In dlgts
> > > > > > If *TEST FOR DELEGATE BEING ON RECEIVER?*

Then > > > > > > ei.RemoveEventHandler(sender, dlgt)
> > > > > > End If
> > > > > > Next dlgt
> > > > > >
> > > > > > Next ei
> > > > > >
> > > > > > End Sub
> > > > > > </code>
> > > > > >
> > > > > > Can someone suggest what might replace the capitalised text? > > > > > Alternatively,
> > > > > > can
> > > > > > anyone think of another way of achieving the same end?
> > > > > >
> > > > > > Thanks.
> > > > > >
> > > > > > Charles
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 20 '05 #11

P: n/a
Jay

Perhaps we can use as the starting point the following code, extracted from
the article that I mentioned a while back. The purpose of this code is to
map handlers in the receiver with events in the sender, based on a pattern
such as 'Event maps to OnEvent'.

<code>
Dim Method As MethodInfo

For Each ei As EventInfo In SenderType.GetEvents()
Method = ReceiverType.GetMethod(prefix & ei.Name & sufix,
bindingAttr)

If Not Method Is Nothing Then
dlgt = [Delegate].CreateDelegate(ei.EventHandlerType,
receiver, Method.Name) '***

If bind Then
ei.AddEventHandler(sender, dlgt)
Else
ei.RemoveEventHandler(sender, dlgt)
End If
End If
Next
</code>

This shows how to create a delegate using information in the EventInfo
class. Can you see how the line marked *** might be modified to create a
delegate based on the sender and not the receiver?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:u9**************@TK2MSFTNGP10.phx.gbl...
Charles,
You would need to get at the underlying field that is used as the backing
store for the Event. Or know the magic key to the Events property.

Remember that an Event simply encapsulates a Delegate Field, similar to how a Property encapsulates other fields.

For example in VB.NET the Changed Event has a ChangeEvent delegate field on the class.

Just as a Property does not need to be implemented in terms of an actual
field, an Event (in C#) does not need to be implemented in terms of a
Delegate Field. In C# the delegates can be stored in the Events property (an EventHandlerList class). VB.NET currently does not support the Events
property.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:uC**************@tk2msftngp13.phx.gbl...
Jay

Perhaps we can approach this in another way. I have repeated my original
code below. If I don't use sender.Events - as you have explained why - is
there a way to create a delegate from ei (an EventInfo object)?

If I could create such a delegate (dlgt) , then I could use
dlgt.GetInvocationList() instead, and I would be well on my way.

What do you think?

Charles

<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal receiver As Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As System.Delegate

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()
' For each event that the sender can raise, get the invocation list
dlgts = sender.Events.Item( *WHAT GOES

HERE?* ).GetInvocationList()

For Each dlgt As System.Delegate In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt
Next ei

End Sub
</code>
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:et**************@TK2MSFTNGP10.phx.gbl...
Charles,
> I didn't mean to suggest that I thought these were the same. Rather than get
> bogged down in (perhaps) my misunderstanding, I will state my aim in PDL >
> For each event that can be raised by an object (sender)
Unfortunately I believe you will need to enable the "Option Psychic On" option, As sender.Events is a secure door, you can only get out what you know you put in. Which is part of the entire point behind Encapsulation. The
object protects the information that it knows, you need to ask the object itself for details, if it decides those details are too important not
to share, well its protecting your from yourself...
> > As I stated, I would expect it to be Nothing or an empty list, is it
an
> > empty list?
>
> I can't tell if it is an empty list because there is no member for
> retrieving the length, and none for indexing either.
I thought I saw that EventHandlerList implemented IEnumerable, you are
correct it doesn't, so obviously you cannot use it for what you want.
Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:ea**************@TK2MSFTNGP10.phx.gbl...
> Jay
>
> > sender.Events is totally different then
Delegate.GetInvocationList. >
> I didn't mean to suggest that I thought these were the same. Rather

than get
> bogged down in (perhaps) my misunderstanding, I will state my aim in PDL >
> For each event that can be raised by an object (sender)
> For each event handler currently attached for the given event
> If given event handler is on known target (receiver)
> Remove handler
> End if
> Next event handler
> Next event
>
> I don't know how to state it any better than that.
>
> > As I stated, I would expect it to be Nothing or an empty list, is it an
> > empty list?
>
> I can't tell if it is an empty list because there is no member for
> retrieving the length, and none for indexing either.
>
> Thanks for your continued help.
>
> Charles
>
>
> "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message
> news:u1***************@tk2msftngp13.phx.gbl...
> > Charles
> > sender.Events is totally different then
Delegate.GetInvocationList. > >
> > Delegate.GetInvocationList is how you see all the handlers to be

called
> for
> > an event.
> >
> > sender.Events is all the invocationlists for all the events on a
> component,
> > if you designed your component to be used that way. (read its a C#
thing).
> >
> > > Incidentally, sender.Events is *not* nothing in my project, and I
have
> > only
> > > called AddHandler to add a handler for an event.
> > As I stated, I would expect it to be Nothing or an empty list, is
it an
> > empty list?
> >
> > Hope this helps
> > Jay
> >
> > "Charles Law" <bl***@nowhere.com> wrote in message
> > news:Oz**************@TK2MSFTNGP09.phx.gbl...
> > > Jay
> > >
> > > I did see once where New Object was used for adding keys, but,
as you
> > > suggest that was in a user rolled method.
> > >
> > > It seems, from what you are saying, that the invocation list is for user
> > use
> > > only. I had expected that the 'framework' would have a method - that
I
> > could
> > > get access to - that allowed me to see all the

handlers/delegates to be
> > > called for an event. After all, if this is not the case, how
does the
> > > framework do it?
> > >
> > > When an event is raised, there must be a list somewhere, of

delegates
> that
> > > will be invoked/called. If I could just get access to/enumerate

those
> > > handlers, I would be home and dry.
> > >
> > > Incidentally, sender.Events is *not* nothing in my project, and
I have
> > only
> > > called AddHandler to add a handler for an event.
> > >
> > > Charles
> > >
> > >
> > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote
in > message
> > > news:%2***************@TK2MSFTNGP09.phx.gbl...
> > > > Charles,
> > > > A specific hidden field that the designer of the class supplied when
> > they
> > > > added the Event to the HandlerList.
> > > >
> > > > I suspect in your project that sender.Events is nothing, or an

empty
> > list.
> > > >
> > > > Generally the class itself will create a key object (via New

Object
> > > > literally) that is used to index into the Events collection.
If you
> are
> > > > using the Events collection you should know what that key is.
In that
> > you
> > > > would have supplied the key to add the event to the collection. > > > >
> > > > Hope this helps
> > > > Jay
> > > >
> > > >
> > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > > > Hi Jay
> > > > >
> > > > > Yes, I think that one of those will allow me to test for

equality
> with
> > > the
> > > > > receiver. My first hurdle, though is this line:
> > > > >
> > > > > > dlgts = sender.Events.Item( *WHAT GOES
> HERE?* ).GetInvocationList()
> > > > >
> > > > > Given the sender object, I cannot for the life of me see how

to > drill
> > > down
> > > > > to the invocation list. The Item member seems to need a key in the
> > shape
> > > > of
> > > > > an object, but what key should I use? I have searched and

searched
> but
> > > > > cannot find an example of this anywhere. Can you think what

might
> > work?
> > > > >
> > > > > Thanks.
> > > > >
> > > > > Charles
> > > > >
> > > > >
> > > > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com>
wrote
in
> > > message
> > > > > news:Om**************@tk2msftngp13.phx.gbl...
> > > > > > Charles,
> > > > > > > For Each dlgt As [Delegate] In dlgts
> > > > > > > If *TEST FOR DELEGATE BEING ON
RECEIVER?* Then
> > > > > >
> > > > > > Remember that [Delegate] is short hand for
System.Delegate. That
> > > > > > System.Delegate is a class with methods & properties.
> > > > > >
> > > > > > I would start by looking at the methods & properties available on
> > the
> > > > > > System.Delegate class.
> > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

http://msdn.microsoft.com/library/de...ClassTopic.asp > > > > > >
> > > > > > Specifically the System.Delegate.Target and System.Delegate Method
> > > > > > properties. The System.Delegate.Equals method may or may not help.
> > > > > >
> > > > > > Hope this helps
> > > > > > Jay
> > > > > >
> > > > > >
> > > > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > > > news:eh**************@TK2MSFTNGP09.phx.gbl...
> > > > > > > Mr "yEaH rIgHt" posted the following link about a week ago in
> > answer
> > > > to
> > > > > my
> > > > > > > question about removing event handlers.
> > > > > > >
> > > > > > > > http://www.vbinfozine.com/t_bindevt.shtml
> > > > > > >
> > > > > > > Following on from that post, the following issues still

exist.
> > > > > > >
> > > > > > > The article shows how to find methods on a receiver that

match
> the
> > > > > pattern
> > > > > > > OnXXXX given the sender. It loops through the sender events and
> > > tries
> > > > to
> > > > > > get
> > > > > > > methods from the receiver that match the pattern. For
each
one
> it
> > > > finds
> > > > > it
> > > > > > > either adds or removes a handler for the event.
> > > > > > >
> > > > > > > This is great where there is a straight forward mapping, but
I
> > don't
> > > > > have
> > > > > > a
> > > > > > > straight forward mapping. For example, although I could

easily
> use
> > > > this
> > > > > > > pattern in many cases, there are situations where the

sender has
> > two
> > > > > > similar
> > > > > > > events, only one of which a particular receiver is going to > > service.
> > > > > > >
> > > > > > > Let's say that my sender has an event ValueChanged. My
receiver
> > > could
> > > > > > easily
> > > > > > > have a method OnValueChanged that could be linked up
using the
> > > > technique
> > > > > > > above. As it happens, my receiver has a method
> > > MyControl_ValueChanged,
> > > > > but
> > > > > > > this also works with the technique above.
> > > > > > >
> > > > > > > The problem arises where my sender has two values that
can > change.
> > > In
> > > > > this
> > > > > > > case it can raise two events: Value1Changed and

Value2Changed.
> My
> > > > > receiver
> > > > > > > only services one of these, and which one is determined at > > runtime.
> > > > > > > Therefore, the receiver still has a method
> MyControl_ValueChanged,
> > > > > because
> > > > > > > it knows nothing of a sender that has two values.
> > > > > > >
> > > > > > > This breaks the pattern, as there is now easy way to

transform
> the
> > > > event
> > > > > > > Value2Changed into the method name MyControl_ValueChanged. > > > > > > >
> > > > > > > So, ...
> > > > > > >
> > > > > > > I am trying to find a way of looping through the sender's > events,
> > as
> > > > > > before,
> > > > > > > but for each one I want to get the invocation list, and

see
if
> my
> > > > > receiver
> > > > > > > is in it. Only if it is do I want to remove the handler. I have
> > got
> > > > this
> > > > > > far
> > > > > > >
> > > > > > > <code>
> > > > > > > Public Shared Sub RemoveHandlers(ByVal sender As

Object, > ByVal
> > > > > > receiver
> > > > > > > As Object)
> > > > > > >
> > > > > > > Dim SenderType As Type
> > > > > > > Dim ReceiverType As Type
> > > > > > >
> > > > > > > Dim dlgts() As [Delegate]
> > > > > > >
> > > > > > > SenderType = sender.GetType()
> > > > > > > ReceiverType = receiver.GetType()
> > > > > > >
> > > > > > > For Each ei As EventInfo In SenderType.GetEvents() > > > > > > >
> > > > > > > ' For each event that the sender can raise, get the
> > > > > invocation
> > > > > > > list
> > > > > > > dlgts = sender.Events.Item( *WHAT GOES
> > > > > > > HERE?* ).GetInvocationList()
> > > > > > >
> > > > > > > For Each dlgt As [Delegate] In dlgts
> > > > > > > If *TEST FOR DELEGATE BEING ON

RECEIVER?* Then
> > > > > > > ei.RemoveEventHandler(sender, dlgt)
> > > > > > > End If
> > > > > > > Next dlgt
> > > > > > >
> > > > > > > Next ei
> > > > > > >
> > > > > > > End Sub
> > > > > > > </code>
> > > > > > >
> > > > > > > Can someone suggest what might replace the capitalised

text?
> > > > > > Alternatively,
> > > > > > > can
> > > > > > > anyone think of another way of achieving the same end?
> > > > > > >
> > > > > > > Thanks.
> > > > > > >
> > > > > > > Charles
> > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 20 '05 #12

P: n/a
Charles,
Perhaps we can use as the starting point the following code, extracted from the article that I mentioned a while back. The purpose of this code is to
map handlers in the receiver with events in the sender, based on a pattern
such as 'Event maps to OnEvent'. Unfortunately you are looking for a "solid" rule, where there is none. :-(

"Event maps to OnEvent" is a coding style, that I suspect most VB.NET
developers, coming from VB6, do not follow.

This shows how to create a delegate using information in the EventInfo
class. Can you see how the line marked *** might be modified to create a
delegate based on the sender and not the receiver? Have you attempted to exchange the sender for the receiver variable and use
the same code?

Thinking about this, rather then trying to hack how Events are currently
implemented in VB.NET. Which is an implementation detail that could change.
I would expect it would be better, more correct, and safer if you
implemented your own Event Dispatcher object. Especially considering you did
mention that you are attempting to connect & disconnect these "events" at
runtime correct? (and not design time).

This Event Dispatch would track the "event", the "object" (receiver), and
the "message" (method to call). I would use a Delegate for the "object" &
"message" pair, and probably a String for the "Event" name, although any
object would work, as suggested by the Event.

The Event Dispatch object would need RaiseEvent, AddHandler, and
RemoveHandler methods, plus any others

I would either make this Event Dispatch object my base class for all the
classes in my project (a Layer Super Type pattern) or each base class would
contain an instance of the Event Dispatch object.

By implementing your own Event Dispatch object, you can add any methods you
need!

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:u5**************@TK2MSFTNGP10.phx.gbl... Jay

Perhaps we can use as the starting point the following code, extracted from the article that I mentioned a while back. The purpose of this code is to
map handlers in the receiver with events in the sender, based on a pattern
such as 'Event maps to OnEvent'.

<code>
Dim Method As MethodInfo

For Each ei As EventInfo In SenderType.GetEvents()
Method = ReceiverType.GetMethod(prefix & ei.Name & sufix,
bindingAttr)

If Not Method Is Nothing Then
dlgt = [Delegate].CreateDelegate(ei.EventHandlerType,
receiver, Method.Name) '***

If bind Then
ei.AddEventHandler(sender, dlgt)
Else
ei.RemoveEventHandler(sender, dlgt)
End If
End If
Next
</code>

This shows how to create a delegate using information in the EventInfo
class. Can you see how the line marked *** might be modified to create a
delegate based on the sender and not the receiver?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:u9**************@TK2MSFTNGP10.phx.gbl...
Charles,
You would need to get at the underlying field that is used as the backing
store for the Event. Or know the magic key to the Events property.

Remember that an Event simply encapsulates a Delegate Field, similar to how
a Property encapsulates other fields.

For example in VB.NET the Changed Event has a ChangeEvent delegate field

on
the class.

Just as a Property does not need to be implemented in terms of an actual
field, an Event (in C#) does not need to be implemented in terms of a
Delegate Field. In C# the delegates can be stored in the Events property

(an
EventHandlerList class). VB.NET currently does not support the Events
property.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:uC**************@tk2msftngp13.phx.gbl...
Jay

Perhaps we can approach this in another way. I have repeated my original code below. If I don't use sender.Events - as you have explained why - is there a way to create a delegate from ei (an EventInfo object)?

If I could create such a delegate (dlgt) , then I could use
dlgt.GetInvocationList() instead, and I would be well on my way.

What do you think?

Charles

<code>
Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal receiver As
Object)

Dim SenderType As Type
Dim ReceiverType As Type

Dim dlgts() As System.Delegate

SenderType = sender.GetType()
ReceiverType = receiver.GetType()

For Each ei As EventInfo In SenderType.GetEvents()
' For each event that the sender can raise, get the invocation list
dlgts = sender.Events.Item( *WHAT GOES

HERE?* ).GetInvocationList()

For Each dlgt As System.Delegate In dlgts
If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
ei.RemoveEventHandler(sender, dlgt)
End If
Next dlgt
Next ei

End Sub
</code>
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:et**************@TK2MSFTNGP10.phx.gbl...
> Charles,
> > I didn't mean to suggest that I thought these were the same.
Rather than
> get
> > bogged down in (perhaps) my misunderstanding, I will state my aim
in PDL
> >
> > For each event that can be raised by an object (sender)
> Unfortunately I believe you will need to enable the "Option Psychic On" > option, As sender.Events is a secure door, you can only get out what you > know you put in. Which is part of the entire point behind Encapsulation. The
> object protects the information that it knows, you need to ask the

object
> itself for details, if it decides those details are too important
not to > share, well its protecting your from yourself...
>
>
> > > As I stated, I would expect it to be Nothing or an empty list,
is
it an
> > > empty list?
> >
> > I can't tell if it is an empty list because there is no member for
> > retrieving the length, and none for indexing either.
> I thought I saw that EventHandlerList implemented IEnumerable, you
are > correct it doesn't, so obviously you cannot use it for what you want. >
>
> Hope this helps
> Jay
>
>
> "Charles Law" <bl***@nowhere.com> wrote in message
> news:ea**************@TK2MSFTNGP10.phx.gbl...
> > Jay
> >
> > > sender.Events is totally different then
Delegate.GetInvocationList. > >
> > I didn't mean to suggest that I thought these were the same. Rather than
> get
> > bogged down in (perhaps) my misunderstanding, I will state my aim
in
PDL
> >
> > For each event that can be raised by an object (sender)
> > For each event handler currently attached for the given event
> > If given event handler is on known target (receiver)
> > Remove handler
> > End if
> > Next event handler
> > Next event
> >
> > I don't know how to state it any better than that.
> >
> > > As I stated, I would expect it to be Nothing or an empty list,
is it an
> > > empty list?
> >
> > I can't tell if it is an empty list because there is no member for
> > retrieving the length, and none for indexing either.
> >
> > Thanks for your continued help.
> >
> > Charles
> >
> >
> > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in
message
> > news:u1***************@tk2msftngp13.phx.gbl...
> > > Charles
> > > sender.Events is totally different then Delegate.GetInvocationList. > > >
> > > Delegate.GetInvocationList is how you see all the handlers to be
called
> > for
> > > an event.
> > >
> > > sender.Events is all the invocationlists for all the events on a
> > component,
> > > if you designed your component to be used that way. (read its a
C# > thing).
> > >
> > > > Incidentally, sender.Events is *not* nothing in my project, and
I have
> > > only
> > > > called AddHandler to add a handler for an event.
> > > As I stated, I would expect it to be Nothing or an empty list,
is
it an
> > > empty list?
> > >
> > > Hope this helps
> > > Jay
> > >
> > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > news:Oz**************@TK2MSFTNGP09.phx.gbl...
> > > > Jay
> > > >
> > > > I did see once where New Object was used for adding keys, but, as you
> > > > suggest that was in a user rolled method.
> > > >
> > > > It seems, from what you are saying, that the invocation list
is for
> user
> > > use
> > > > only. I had expected that the 'framework' would have a
method - that
I
> > > could
> > > > get access to - that allowed me to see all the handlers/delegates
to
> be
> > > > called for an event. After all, if this is not the case, how
does the
> > > > framework do it?
> > > >
> > > > When an event is raised, there must be a list somewhere, of
delegates
> > that
> > > > will be invoked/called. If I could just get access
to/enumerate those
> > > > handlers, I would be home and dry.
> > > >
> > > > Incidentally, sender.Events is *not* nothing in my project, and I have
> > > only
> > > > called AddHandler to add a handler for an event.
> > > >
> > > > Charles
> > > >
> > > >
> > > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in > > message
> > > > news:%2***************@TK2MSFTNGP09.phx.gbl...
> > > > > Charles,
> > > > > A specific hidden field that the designer of the class supplied when
> > > they
> > > > > added the Event to the HandlerList.
> > > > >
> > > > > I suspect in your project that sender.Events is nothing, or
an empty
> > > list.
> > > > >
> > > > > Generally the class itself will create a key object (via New
Object
> > > > > literally) that is used to index into the Events collection.
If you
> > are
> > > > > using the Events collection you should know what that key is. In
> that
> > > you
> > > > > would have supplied the key to add the event to the collection. > > > > >
> > > > > Hope this helps
> > > > > Jay
> > > > >
> > > > >
> > > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > > > > Hi Jay
> > > > > >
> > > > > > Yes, I think that one of those will allow me to test for
equality
> > with
> > > > the
> > > > > > receiver. My first hurdle, though is this line:
> > > > > >
> > > > > > > dlgts = sender.Events.Item( *WHAT GOES
> > HERE?* ).GetInvocationList()
> > > > > >
> > > > > > Given the sender object, I cannot for the life of me see
how to
> > drill
> > > > down
> > > > > > to the invocation list. The Item member seems to need a
key
in the
> > > shape
> > > > > of
> > > > > > an object, but what key should I use? I have searched and
searched
> > but
> > > > > > cannot find an example of this anywhere. Can you think
what might
> > > work?
> > > > > >
> > > > > > Thanks.
> > > > > >
> > > > > > Charles
> > > > > >
> > > > > >
> > > > > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com>
wrote in
> > > > message
> > > > > > news:Om**************@tk2msftngp13.phx.gbl...
> > > > > > > Charles,
> > > > > > > > For Each dlgt As [Delegate] In dlgts
> > > > > > > > If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
> > > > > > >
> > > > > > > Remember that [Delegate] is short hand for System.Delegate. That
> > > > > > > System.Delegate is a class with methods & properties.
> > > > > > >
> > > > > > > I would start by looking at the methods & properties

available
> on
> > > the
> > > > > > > System.Delegate class.
> > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

http://msdn.microsoft.com/library/de...ClassTopic.asp
> > > > > > >
> > > > > > > Specifically the System.Delegate.Target and System.Delegate > Method
> > > > > > > properties. The System.Delegate.Equals method may or may not > help.
> > > > > > >
> > > > > > > Hope this helps
> > > > > > > Jay
> > > > > > >
> > > > > > >
> > > > > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > > > > news:eh**************@TK2MSFTNGP09.phx.gbl...
> > > > > > > > Mr "yEaH rIgHt" posted the following link about a week ago in
> > > answer
> > > > > to
> > > > > > my
> > > > > > > > question about removing event handlers.
> > > > > > > >
> > > > > > > > > http://www.vbinfozine.com/t_bindevt.shtml
> > > > > > > >
> > > > > > > > Following on from that post, the following issues still exist.
> > > > > > > >
> > > > > > > > The article shows how to find methods on a receiver that match
> > the
> > > > > > pattern
> > > > > > > > OnXXXX given the sender. It loops through the sender

events
> and
> > > > tries
> > > > > to
> > > > > > > get
> > > > > > > > methods from the receiver that match the pattern. For each one
> > it
> > > > > finds
> > > > > > it
> > > > > > > > either adds or removes a handler for the event.
> > > > > > > >
> > > > > > > > This is great where there is a straight forward mapping, but
I
> > > don't
> > > > > > have
> > > > > > > a
> > > > > > > > straight forward mapping. For example, although I
could easily
> > use
> > > > > this
> > > > > > > > pattern in many cases, there are situations where the

sender
> has
> > > two
> > > > > > > similar
> > > > > > > > events, only one of which a particular receiver is going
to
> > > service.
> > > > > > > >
> > > > > > > > Let's say that my sender has an event ValueChanged. My
> receiver
> > > > could
> > > > > > > easily
> > > > > > > > have a method OnValueChanged that could be linked up using the
> > > > > technique
> > > > > > > > above. As it happens, my receiver has a method
> > > > MyControl_ValueChanged,
> > > > > > but
> > > > > > > > this also works with the technique above.
> > > > > > > >
> > > > > > > > The problem arises where my sender has two values that can > > change.
> > > > In
> > > > > > this
> > > > > > > > case it can raise two events: Value1Changed and
Value2Changed.
> > My
> > > > > > receiver
> > > > > > > > only services one of these, and which one is
determined at > > > runtime.
> > > > > > > > Therefore, the receiver still has a method
> > MyControl_ValueChanged,
> > > > > > because
> > > > > > > > it knows nothing of a sender that has two values.
> > > > > > > >
> > > > > > > > This breaks the pattern, as there is now easy way to
transform
> > the
> > > > > event
> > > > > > > > Value2Changed into the method name MyControl_ValueChanged. > > > > > > > >
> > > > > > > > So, ...
> > > > > > > >
> > > > > > > > I am trying to find a way of looping through the sender's > > events,
> > > as
> > > > > > > before,
> > > > > > > > but for each one I want to get the invocation list,
and see
if
> > my
> > > > > > receiver
> > > > > > > > is in it. Only if it is do I want to remove the
handler.
I > have
> > > got
> > > > > this
> > > > > > > far
> > > > > > > >
> > > > > > > > <code>
> > > > > > > > Public Shared Sub RemoveHandlers(ByVal sender As

Object,
> > ByVal
> > > > > > > receiver
> > > > > > > > As Object)
> > > > > > > >
> > > > > > > > Dim SenderType As Type
> > > > > > > > Dim ReceiverType As Type
> > > > > > > >
> > > > > > > > Dim dlgts() As [Delegate]
> > > > > > > >
> > > > > > > > SenderType = sender.GetType()
> > > > > > > > ReceiverType = receiver.GetType()
> > > > > > > >
> > > > > > > > For Each ei As EventInfo In SenderType.GetEvents() > > > > > > > >
> > > > > > > > ' For each event that the sender can
raise, get
> the
> > > > > > invocation
> > > > > > > > list
> > > > > > > > dlgts = sender.Events.Item( *WHAT GOES
> > > > > > > > HERE?* ).GetInvocationList()
> > > > > > > >
> > > > > > > > For Each dlgt As [Delegate] In dlgts
> > > > > > > > If *TEST FOR DELEGATE BEING ON

RECEIVER?* Then
> > > > > > > > ei.RemoveEventHandler(sender,

dlgt) > > > > > > > > End If
> > > > > > > > Next dlgt
> > > > > > > >
> > > > > > > > Next ei
> > > > > > > >
> > > > > > > > End Sub
> > > > > > > > </code>
> > > > > > > >
> > > > > > > > Can someone suggest what might replace the capitalised text?
> > > > > > > Alternatively,
> > > > > > > > can
> > > > > > > > anyone think of another way of achieving the same end?
> > > > > > > >
> > > > > > > > Thanks.
> > > > > > > >
> > > > > > > > Charles
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 20 '05 #13

P: n/a
Jay

I did try exchanging sender for receiver, but the Method.Name is also based
on the receiver, and does not exist on the sender.

It seems like I am wishing for the moon on a stick, and that the only way
forward is to roll my own, as you suggest. It does seem a lot of trouble to
go to though, when .NET basically has what I need built-in. I feel that I am
missing a trick somewhere.

Anyway, onwards and upwards.

Thanks again for your help.

Cheers.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:ev**************@TK2MSFTNGP09.phx.gbl...
Charles,
Perhaps we can use as the starting point the following code, extracted from
the article that I mentioned a while back. The purpose of this code is to
map handlers in the receiver with events in the sender, based on a pattern such as 'Event maps to OnEvent'.

Unfortunately you are looking for a "solid" rule, where there is none. :-(

"Event maps to OnEvent" is a coding style, that I suspect most VB.NET
developers, coming from VB6, do not follow.

This shows how to create a delegate using information in the EventInfo
class. Can you see how the line marked *** might be modified to create a
delegate based on the sender and not the receiver?

Have you attempted to exchange the sender for the receiver variable and

use the same code?

Thinking about this, rather then trying to hack how Events are currently
implemented in VB.NET. Which is an implementation detail that could change.

I would expect it would be better, more correct, and safer if you
implemented your own Event Dispatcher object. Especially considering you did mention that you are attempting to connect & disconnect these "events" at
runtime correct? (and not design time).

This Event Dispatch would track the "event", the "object" (receiver), and
the "message" (method to call). I would use a Delegate for the "object" &
"message" pair, and probably a String for the "Event" name, although any
object would work, as suggested by the Event.

The Event Dispatch object would need RaiseEvent, AddHandler, and
RemoveHandler methods, plus any others

I would either make this Event Dispatch object my base class for all the
classes in my project (a Layer Super Type pattern) or each base class would contain an instance of the Event Dispatch object.

By implementing your own Event Dispatch object, you can add any methods you need!

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:u5**************@TK2MSFTNGP10.phx.gbl...
Jay

Perhaps we can use as the starting point the following code, extracted from
the article that I mentioned a while back. The purpose of this code is to map handlers in the receiver with events in the sender, based on a pattern such as 'Event maps to OnEvent'.

<code>
Dim Method As MethodInfo

For Each ei As EventInfo In SenderType.GetEvents()
Method = ReceiverType.GetMethod(prefix & ei.Name & sufix,
bindingAttr)

If Not Method Is Nothing Then
dlgt = [Delegate].CreateDelegate(ei.EventHandlerType,
receiver, Method.Name) '***

If bind Then
ei.AddEventHandler(sender, dlgt)
Else
ei.RemoveEventHandler(sender, dlgt)
End If
End If
Next
</code>

This shows how to create a delegate using information in the EventInfo
class. Can you see how the line marked *** might be modified to create a
delegate based on the sender and not the receiver?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:u9**************@TK2MSFTNGP10.phx.gbl...
Charles,
You would need to get at the underlying field that is used as the backing store for the Event. Or know the magic key to the Events property.

Remember that an Event simply encapsulates a Delegate Field, similar to how
a Property encapsulates other fields.

For example in VB.NET the Changed Event has a ChangeEvent delegate
field
on
the class.

Just as a Property does not need to be implemented in terms of an
actual field, an Event (in C#) does not need to be implemented in terms of a
Delegate Field. In C# the delegates can be stored in the Events property (an
EventHandlerList class). VB.NET currently does not support the Events
property.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:uC**************@tk2msftngp13.phx.gbl...
> Jay
>
> Perhaps we can approach this in another way. I have repeated my original > code below. If I don't use sender.Events - as you have explained
why - is
> there a way to create a delegate from ei (an EventInfo object)?
>
> If I could create such a delegate (dlgt) , then I could use
> dlgt.GetInvocationList() instead, and I would be well on my way.
>
> What do you think?
>
> Charles
>
> <code>
> Public Shared Sub RemoveHandlers(ByVal sender As Object, ByVal receiver
As
> Object)
>
> Dim SenderType As Type
> Dim ReceiverType As Type
>
> Dim dlgts() As System.Delegate
>
> SenderType = sender.GetType()
> ReceiverType = receiver.GetType()
>
> For Each ei As EventInfo In SenderType.GetEvents()
> ' For each event that the sender can raise, get the

invocation list
> dlgts = sender.Events.Item( *WHAT GOES
HERE?* ).GetInvocationList()
>
> For Each dlgt As System.Delegate In dlgts
> If *TEST FOR DELEGATE BEING ON RECEIVER?* Then
> ei.RemoveEventHandler(sender, dlgt)
> End If
> Next dlgt
> Next ei
>
> End Sub
> </code>
>
>
> "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message
> news:et**************@TK2MSFTNGP10.phx.gbl...
> > Charles,
> > > I didn't mean to suggest that I thought these were the same.

Rather than
> > get
> > > bogged down in (perhaps) my misunderstanding, I will state my aim in
PDL
> > >
> > > For each event that can be raised by an object (sender)
> > Unfortunately I believe you will need to enable the "Option
Psychic On"
> > option, As sender.Events is a secure door, you can only get out
what you
> > know you put in. Which is part of the entire point behind Encapsulation.
> The
> > object protects the information that it knows, you need to ask the
object
> > itself for details, if it decides those details are too important not
to
> > share, well its protecting your from yourself...
> >
> >
> > > > As I stated, I would expect it to be Nothing or an empty list,

is
it
> an
> > > > empty list?
> > >
> > > I can't tell if it is an empty list because there is no member

for > > > retrieving the length, and none for indexing either.
> > I thought I saw that EventHandlerList implemented IEnumerable, you

are > > correct it doesn't, so obviously you cannot use it for what you want. > >
> >
> > Hope this helps
> > Jay
> >
> >
> > "Charles Law" <bl***@nowhere.com> wrote in message
> > news:ea**************@TK2MSFTNGP10.phx.gbl...
> > > Jay
> > >
> > > > sender.Events is totally different then

Delegate.GetInvocationList.
> > >
> > > I didn't mean to suggest that I thought these were the same. Rather than
> > get
> > > bogged down in (perhaps) my misunderstanding, I will state my aim in
PDL
> > >
> > > For each event that can be raised by an object (sender)
> > > For each event handler currently attached for the given
event > > > If given event handler is on known target (receiver)
> > > Remove handler
> > > End if
> > > Next event handler
> > > Next event
> > >
> > > I don't know how to state it any better than that.
> > >
> > > > As I stated, I would expect it to be Nothing or an empty list,
is
it
> an
> > > > empty list?
> > >
> > > I can't tell if it is an empty list because there is no member for > > > retrieving the length, and none for indexing either.
> > >
> > > Thanks for your continued help.
> > >
> > > Charles
> > >
> > >
> > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in > message
> > > news:u1***************@tk2msftngp13.phx.gbl...
> > > > Charles
> > > > sender.Events is totally different then

Delegate.GetInvocationList.
> > > >
> > > > Delegate.GetInvocationList is how you see all the handlers to be > called
> > > for
> > > > an event.
> > > >
> > > > sender.Events is all the invocationlists for all the events on a > > > component,
> > > > if you designed your component to be used that way. (read its a C# > > thing).
> > > >
> > > > > Incidentally, sender.Events is *not* nothing in my project, and
I
> have
> > > > only
> > > > > called AddHandler to add a handler for an event.
> > > > As I stated, I would expect it to be Nothing or an empty list,
is
it
> an
> > > > empty list?
> > > >
> > > > Hope this helps
> > > > Jay
> > > >
> > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > news:Oz**************@TK2MSFTNGP09.phx.gbl...
> > > > > Jay
> > > > >
> > > > > I did see once where New Object was used for adding keys,

but, as
> you
> > > > > suggest that was in a user rolled method.
> > > > >
> > > > > It seems, from what you are saying, that the invocation list is for
> > user
> > > > use
> > > > > only. I had expected that the 'framework' would have a method - that
> I
> > > > could
> > > > > get access to - that allowed me to see all the

handlers/delegates
to
> > be
> > > > > called for an event. After all, if this is not the case, how

does
> the
> > > > > framework do it?
> > > > >
> > > > > When an event is raised, there must be a list somewhere, of
> delegates
> > > that
> > > > > will be invoked/called. If I could just get access to/enumerate > those
> > > > > handlers, I would be home and dry.
> > > > >
> > > > > Incidentally, sender.Events is *not* nothing in my project, and
I
> have
> > > > only
> > > > > called AddHandler to add a handler for an event.
> > > > >
> > > > > Charles
> > > > >
> > > > >
> > > > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com>

wrote in
> > > message
> > > > > news:%2***************@TK2MSFTNGP09.phx.gbl...
> > > > > > Charles,
> > > > > > A specific hidden field that the designer of the class

supplied
> when
> > > > they
> > > > > > added the Event to the HandlerList.
> > > > > >
> > > > > > I suspect in your project that sender.Events is nothing,
or an > empty
> > > > list.
> > > > > >
> > > > > > Generally the class itself will create a key object (via
New > Object
> > > > > > literally) that is used to index into the Events collection. If
> you
> > > are
> > > > > > using the Events collection you should know what that key is.
In
> > that
> > > > you
> > > > > > would have supplied the key to add the event to the

collection.
> > > > > >
> > > > > > Hope this helps
> > > > > > Jay
> > > > > >
> > > > > >
> > > > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > > > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > > > > > Hi Jay
> > > > > > >
> > > > > > > Yes, I think that one of those will allow me to test for
> equality
> > > with
> > > > > the
> > > > > > > receiver. My first hurdle, though is this line:
> > > > > > >
> > > > > > > > dlgts = sender.Events.Item( *WHAT GOES
> > > HERE?* ).GetInvocationList()
> > > > > > >
> > > > > > > Given the sender object, I cannot for the life of me see

how to
> > > drill
> > > > > down
> > > > > > > to the invocation list. The Item member seems to need a key
in
> the
> > > > shape
> > > > > > of
> > > > > > > an object, but what key should I use? I have searched

and > searched
> > > but
> > > > > > > cannot find an example of this anywhere. Can you think

what > might
> > > > work?
> > > > > > >
> > > > > > > Thanks.
> > > > > > >
> > > > > > > Charles
> > > > > > >
> > > > > > >
> > > > > > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com>

wrote
> in
> > > > > message
> > > > > > > news:Om**************@tk2msftngp13.phx.gbl...
> > > > > > > > Charles,
> > > > > > > > > For Each dlgt As [Delegate] In dlgts
> > > > > > > > > If *TEST FOR DELEGATE BEING ON

RECEIVER?*
> Then
> > > > > > > >
> > > > > > > > Remember that [Delegate] is short hand for

System.Delegate.
> That
> > > > > > > > System.Delegate is a class with methods & properties.
> > > > > > > >
> > > > > > > > I would start by looking at the methods & properties
available
> > on
> > > > the
> > > > > > > > System.Delegate class.
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

http://msdn.microsoft.com/library/de...ClassTopic.asp
> > > > > > > >
> > > > > > > > Specifically the System.Delegate.Target and

System.Delegate
> > Method
> > > > > > > > properties. The System.Delegate.Equals method may or may not
> > help.
> > > > > > > >
> > > > > > > > Hope this helps
> > > > > > > > Jay
> > > > > > > >
> > > > > > > >
> > > > > > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > > > > > news:eh**************@TK2MSFTNGP09.phx.gbl...
> > > > > > > > > Mr "yEaH rIgHt" posted the following link about a
week
ago
> in
> > > > answer
> > > > > > to
> > > > > > > my
> > > > > > > > > question about removing event handlers.
> > > > > > > > >
> > > > > > > > > > http://www.vbinfozine.com/t_bindevt.shtml
> > > > > > > > >
> > > > > > > > > Following on from that post, the following issues still > exist.
> > > > > > > > >
> > > > > > > > > The article shows how to find methods on a receiver that > match
> > > the
> > > > > > > pattern
> > > > > > > > > OnXXXX given the sender. It loops through the sender
events
> > and
> > > > > tries
> > > > > > to
> > > > > > > > get
> > > > > > > > > methods from the receiver that match the pattern.
For each
> one
> > > it
> > > > > > finds
> > > > > > > it
> > > > > > > > > either adds or removes a handler for the event.
> > > > > > > > >
> > > > > > > > > This is great where there is a straight forward mapping, but
> I
> > > > don't
> > > > > > > have
> > > > > > > > a
> > > > > > > > > straight forward mapping. For example, although I could > easily
> > > use
> > > > > > this
> > > > > > > > > pattern in many cases, there are situations where
the sender
> > has
> > > > two
> > > > > > > > similar
> > > > > > > > > events, only one of which a particular receiver is

going to
> > > > service.
> > > > > > > > >
> > > > > > > > > Let's say that my sender has an event ValueChanged. My > > receiver
> > > > > could
> > > > > > > > easily
> > > > > > > > > have a method OnValueChanged that could be linked up

using
> the
> > > > > > technique
> > > > > > > > > above. As it happens, my receiver has a method
> > > > > MyControl_ValueChanged,
> > > > > > > but
> > > > > > > > > this also works with the technique above.
> > > > > > > > >
> > > > > > > > > The problem arises where my sender has two values that can
> > > change.
> > > > > In
> > > > > > > this
> > > > > > > > > case it can raise two events: Value1Changed and
> Value2Changed.
> > > My
> > > > > > > receiver
> > > > > > > > > only services one of these, and which one is determined
at
> > > > runtime.
> > > > > > > > > Therefore, the receiver still has a method
> > > MyControl_ValueChanged,
> > > > > > > because
> > > > > > > > > it knows nothing of a sender that has two values.
> > > > > > > > >
> > > > > > > > > This breaks the pattern, as there is now easy way to
> transform
> > > the
> > > > > > event
> > > > > > > > > Value2Changed into the method name

MyControl_ValueChanged.
> > > > > > > > >
> > > > > > > > > So, ...
> > > > > > > > >
> > > > > > > > > I am trying to find a way of looping through the

sender's
> > > events,
> > > > as
> > > > > > > > before,
> > > > > > > > > but for each one I want to get the invocation list,

and see
> if
> > > my
> > > > > > > receiver
> > > > > > > > > is in it. Only if it is do I want to remove the handler.
I
> > have
> > > > got
> > > > > > this
> > > > > > > > far
> > > > > > > > >
> > > > > > > > > <code>
> > > > > > > > > Public Shared Sub RemoveHandlers(ByVal sender As
Object,
> > > ByVal
> > > > > > > > receiver
> > > > > > > > > As Object)
> > > > > > > > >
> > > > > > > > > Dim SenderType As Type
> > > > > > > > > Dim ReceiverType As Type
> > > > > > > > >
> > > > > > > > > Dim dlgts() As [Delegate]
> > > > > > > > >
> > > > > > > > > SenderType = sender.GetType()
> > > > > > > > > ReceiverType = receiver.GetType()
> > > > > > > > >
> > > > > > > > > For Each ei As EventInfo In

SenderType.GetEvents()
> > > > > > > > >
> > > > > > > > > ' For each event that the sender can

raise, get
> > the
> > > > > > > invocation
> > > > > > > > > list
> > > > > > > > > dlgts = sender.Events.Item( *WHAT GOES
> > > > > > > > > HERE?* ).GetInvocationList()
> > > > > > > > >
> > > > > > > > > For Each dlgt As [Delegate] In dlgts
> > > > > > > > > If *TEST FOR DELEGATE BEING ON

RECEIVER?*
> Then
> > > > > > > > > ei.RemoveEventHandler(sender, dlgt) > > > > > > > > > End If
> > > > > > > > > Next dlgt
> > > > > > > > >
> > > > > > > > > Next ei
> > > > > > > > >
> > > > > > > > > End Sub
> > > > > > > > > </code>
> > > > > > > > >
> > > > > > > > > Can someone suggest what might replace the capitalised > text?
> > > > > > > > Alternatively,
> > > > > > > > > can
> > > > > > > > > anyone think of another way of achieving the same

end? > > > > > > > > >
> > > > > > > > > Thanks.
> > > > > > > > >
> > > > > > > > > Charles
> > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 20 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.