Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,

I need to pass an event as a parameter to a function and I'm wondering if there is any way of doing this.

The reason why I need to do this is because I have a sequence of two lines of code that is littered all over my program, where I dynamically remove the handler to an event, then set the handler again. I'm doing this for several different events and event handlers, so I've decided to write a function that does this.

As an example, let's say I have a combobox in my code called combobox1, and I have the handler called indexChangedHandler. In several places of my code, I have the following two lines:

<br />
RemoveHandler combobox1.SelectedIndexChanged, AddressOf indexChangedHandler<br />
AddHandler combobox1.SelectedIndexChanged, AddressOf indexChangedHandler<br />


Now, I don't want to keep on repeating the above two lines of code (or similar) all over my program, so I'm looking for a way to do this:

<br />
 Private Sub setHandler(evt As Event, hndler As eventhandler)<br />
        RemoveHandler evt, hndler<br />
        AddHandler evt, hndler<br />
 End Sub<br />


so that everywhere where those two lines of code(or similar) occur in my program, I can just replace them with:

<br />
 setHandler(combobox1.SelectedIndexChanged, AddressOf indexChangedHandler)<br />


So far, the "evt as Event" part of the argument of the setHandler function is giving an error. Any ideas on the right way to do this will be very welcomed. Thanks.
Posted

You can use reflection.

VB.NET
Imports System.Reflection

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

        Me.setHandler("Click", CType(AddressOf test, EventHandler), Me.Button1)
        Me.setHandler("Click", CType(AddressOf test, EventHandler), Me.Button1)
        Me.setHandler("Click", CType(AddressOf test, EventHandler), Me.Button1)
    End Sub

    Sub setHandler(eventName As String, handler As [Delegate], o As Object)
        Dim eInfo As EventInfo = o.GetType.GetEvent(eventName, BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.IgnoreCase)
        eInfo.RemoveEventHandler(o, handler)
        eInfo.AddEventHandler(o, handler)
    End Sub

    Sub test(sender As Object, e As EventArgs)
        MsgBox("Ok")
    End Sub

End Class
 
Share this answer
 
Comments
Ralf Meier 13-Jan-16 0:56am    
You have seen that this question is little bit "old" ...
But nevertheless - your answer was good.
So +5 from me ...
There is no use for this code:
VB
Private Sub setHandler(evt As Event, hndler As eventhandler)
RemoveHandler evt, hndler
AddHandler evt, hndler
End Sub


You remove and then add the same handler. It's useless to do this. It's somewhat the same as this code:

temp = a
a = 100
a = temp


Maybe explain what you want to achieve so I can maybe give you a solution for that :-D

Good luck!
 
Share this answer
 
Comments
TraceD 9-Nov-10 6:14am    
Hello Nijboer,

thanks for your reply.

It's been a while since I last coded in VB.Net but I do remember a while back, that dynamically adding an event handler n-times meant that thesame handler was executed n-times. To avoid this, i.e to ensure that the handler is added just once, I first remove the handler each time I want to add the handler dynamically.

You might be asking why the handler would be added several times in the first place... The reason is because I add the handler only after a particular event, say E1, in my form has occured (I add the handler within the handler of event E1). And event E1 can occur several times within my form. If I do not remove the handler each time before adding it again, the handler gets added and thus executed several times.

I could be wrong in my reasoning, perhaps I'm not remembering right, that when a handler is added several times, it is also executed the same number of times it was added. Infact, that's easy to test, and I will shortly after this. But either way, right or wrong, my main interest right now is how I could pass the event as a parameter. The processing being done within the function is not what ultimately interests me right now, so finding a way to circumvent that is not extremely important though not also unimportant
TraceD 9-Nov-10 6:27am    
Hello Nijboer once again,

I just tested that behaviour and yes, it does behave the way I remember. To test it, I created a form called form1 as follows:


Public Class Form1

Dim numberOfHandlerExecutions As Integer = 0

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

AddHandler MyBase.Click, AddressOf Form1_Click
AddHandler MyBase.Click, AddressOf Form1_Click
AddHandler MyBase.Click, AddressOf Form1_Click
End Sub

Private Sub Form1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
numberOfHandlerExecutions = numberOfHandlerExecutions + 1
MsgBox(numberOfHandlerExecutions)
End Sub

End Class



When the form is loaded and I click on the form, the message box appears three times, for each time I dynamically added the handler...
E.F. Nijboer 9-Nov-10 13:04pm    
I indeed know it is possible to add a handler multiple times, but because you give the address of the handler you can only remove/add this known handler and not any other method somewhere else. But I understand what you want and you should pass the control because a property cannot be passed by reference, so change the methods like this:

Private Sub setClickHandler(ctrl As Control, hndler As eventhandler)
RemoveHandler ctrl.Click, hndler
AddHandler ctrl.Click, hndler
End Sub

setClickHandler(textbox1, AddressOf textboxClick)

I know what you're thinking... 'this makes it much less efficient' but this is a language restriction.
TraceD 10-Nov-10 4:00am    
Thanks Nijboer, for your suggestion. Even though it is not exactly what I needed, this will still help clean up my code a little bit, since most of the time, I'm dealing with the same event.

Before marking this post as the accepted answer however, I'll leave this question up for a couple of days just incase someone comes up with another suggestion that's closer to what I need.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900