10

I need to pass a reference of a function to another function in VB.NET. How can this be done?

My function needs to use AddHandler internally, for which I need to pass it a handling function. My code below obviously does not work, but it conveys the idea of what I need.

Public Function CreateMenuItem(ByVal Name As String, ByRef Func As AddressOf ) As MenuItem
   Dim item As New MenuItem

   item.Name = Name
   'item.  other options

   AddHandler item.Click, AddressOf Func

   Return item
End Function

Is there another way to do this? The AddHandler needs to be set to a passed parameter in a function somehow...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DieSlower
  • 252
  • 1
  • 3
  • 8
  • `Addressof` returns a delegate. Your function should therefore accept the given delegate as the parameter type. – asawyer May 24 '13 at 17:09

3 Answers3

13

A function delegate is just what you need to do this. First you need to define the delegate somewhere in the class. Change the signature to fit your event of course.

Public Delegate Sub MyDelegate(sender As System.Object, e As System.EventArgs)

Your function will take the delegate as an argument.

Public Function CreateMenuItem(ByVal Name As String, del As MyDelegate) As MenuItem
  ''''
  AddHandler item.Click, del
  ''''
End Function

Public Sub MyEventHandler(sender As System.Object, e As System.EventArgs)
  ''''
End Sub

And here's how you call the function:

CreateMenuItem(myString, AddressOf MyEventHandler)
Fuzhou Hu
  • 528
  • 2
  • 8
  • 1
    If AddHandler instruction gives error, try setting 'del' parameter as EventHandler instead of MyDelegate in CreateMenuItem. (ref. @Janez Lukan solution) – Fil Aug 06 '16 at 13:25
9

Your second argument in the function should be of type EventHandler, and your function would then look like:

Public Function CreateMenuItem(ByVal Name As String, ByRef Func As EventHandler) As MenuItem
    Dim item As New MenuItem

    item.Name = Name
    'item.  Other options

    AddHandler item.Click, Func

    Return item
End Function

Now you need a method to handle those clicks:

Private Sub ItemClick(sender As Object, e As EventArgs)
    'Do something with that click here
End Sub

And you can consume those two methods now with something like:

    Dim handler = New EventHandler(AddressOf ItemClick)
    Dim i = CreateMenuItem("My item", handler)

    i.PerformClick()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Janez Lukan
  • 1,439
  • 1
  • 12
  • 28
1

First off, event handlers have to have Subs. Secondly, AddressOf can't be used as a type. If the sub is in the same class, just use the sub name. If it's in another class/file, you might have to make the sub public and/or qualify it as being a member of the other class. Subs for the AddHandler clause must basically follow the pattern:

Public/Private Sub MyHandler(sender As Object, e As EventArgs)

If you need different routines based on the name of the menu item, you could use one handler and call the appropriate routine based on the name of the item triggering the event.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tinstaafl
  • 6,908
  • 2
  • 15
  • 22
  • Right, i know AddressOf cant be a data type. That was just to convey the idea. And I know how to use AddHandler. But if lets say the handler function is in another class, and CreateMenuItem is public, how can i pass the the address of the handler function from that class to CreateMenuItem? Each menu Item created should have a different handler. I want to avoid having a huge switch or if..else statement list. – DieSlower May 24 '13 at 18:46