0

I'm try to improve our dynamic reporting system. I would like to add event handle to the object I've dynamically created on the form. One of the functions of this would be to populate a listbox from what was selected in the first listbox. i.e. The user select a town and the second listbox is populated by all the people living in that town.

The objectaction and objectactionfunction would be stored in a SQL table in the system. I would also like to store the objectactionfunction code in the table and dynamically create it at runtime. I've been looking into CodeDOM. Am I looking in the right direction. Pseudocode below

dim objectaction as string
dim objectactionfunction as string
objectaction = "LostFocus"
objectactionfunction =" "

addHandler textbox1.objectaction, addressof objectactionfunction
Sean ZA
  • 5
  • 1
  • 4
  • If you want to use `Strings` to store the names of identifiers then you probably need to look into Reflection. I've never tried to register an event handler using Reflection but I'd assume that it is possible, as you can do things like get property values and invoke methods. Reflection code is rather verbose but that's just the nature of the beast. – jmcilhinney Jun 02 '21 at 10:10

1 Answers1

1

Here is an example of using Reflection to register an event handler using Strings to specify the event name and the event handler name:

Imports System.Reflection

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim eventName = "Leave"
        Dim methodName = "TextBox1_Leave"

        Dim targetType = TextBox1.GetType()
        Dim [event] = targetType.GetEvent(eventName)
        Dim eventHandlerType = [event].EventHandlerType
        Dim eventHandlerMethod = Me.GetType().GetMethod(methodName, BindingFlags.NonPublic Or BindingFlags.Instance)
        Dim eventHandlerDelegate = eventHandlerMethod.CreateDelegate(eventHandlerType, Me)

        [event].AddEventHandler(TextBox1, eventHandlerDelegate)
    End Sub

    Private Sub TextBox1_Leave(sender As Object, e As EventArgs)
        MessageBox.Show("Success!")
    End Sub

End Class

As I said in my comment, the code is rather verbose but that's the way it goes. Here's an extension method that you can use to write code once and use it wherever you like:

Imports System.Reflection
Imports System.Runtime.CompilerServices

Public Module ObjectExtensions

    <Extension>
    Public Sub AddEventHandler(source As Object,
                               eventName As String,
                               eventHandlerName As String,
                               eventHandlerSource As Object)
        Dim [event] = source.GetType().GetEvent(eventName)
        Dim eventHandlerMethod = eventHandlerSource.GetType().GetMethod(eventHandlerName, BindingFlags.NonPublic Or BindingFlags.Instance)
        Dim eventHandlerDelegate = eventHandlerMethod.CreateDelegate([event].EventHandlerType, eventHandlerSource)

        [event].AddEventHandler(source, eventHandlerDelegate)
    End Sub

End Module

Sample usage:

Dim eventName = "Leave"
Dim methodName = "TextBox1_Leave"

TextBox1.AddEventHandler(eventName, methodName, Me)
jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
  • Hi jmcilhinney, Thank you so much for the code it has help me solve the first part of my problem. Now for the second part how do you create the below from variable and get it to run ' Private Sub TextBox1_Leave(sender As Object, e As EventArgs) MessageBox.Show("Success!") End Sub' – Sean ZA Jun 02 '21 at 14:59
  • @SeanZA, I have demonstrated that in the answer. Assuming you are using the extension method, you call it on the object whose event you want to handle and pass the name of the event as a `String`, the name of the method to handle the event as a `String` and the object that the event handler is a member of. If I read your question correctly, those two `String` values are coming from your database. If you're handling an event of a `TextBox` then presumably you are running the code in a form, so the form itself would likely own the method, hence `Me`. – jmcilhinney Jun 03 '21 at 00:02
  • @SeanZA, I reread your question and I see that you also want the event handler code stored in the database. Sorry, I missed that first time around. That is another matter. Particularly given that you have accepted this answer, I'd probably suggest that you create another question about the event handler code, because that's a different thing to registering the event handler. – jmcilhinney Jun 03 '21 at 01:09