首页 > 解决方案 > 使用变量作为动作动态创建事件句柄

问题描述

我正在尝试改进我们的动态报告系统。我想将事件句柄添加到我在表单上动态创建的对象。其中一个功能是从第一个列表框中选择的内容填充列表框。即用户选择一个城镇,第二个列表框由居住在该城镇的所有人组成。

objectaction 和 objectactionfunction 将存储在系统的 SQL 表中。我还想将objectactionfunction代码存储在表中,并在运行时动态创建它。我一直在研究 CodeDOM。我在寻找正确的方向吗?下面的伪代码

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

addHandler textbox1.objectaction, addressof objectactionfunction

标签: vb.netcodedomaddhandler

解决方案


下面是一个使用反射来注册事件处理程序的示例,Strings用于指定事件名称和事件处理程序名称:

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

正如我在评论中所说,代码相当冗长,但就是这样。这是一个扩展方法,您可以使用它编写一次代码并在任何您喜欢的地方使用它:

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

示例用法:

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

TextBox1.AddEventHandler(eventName, methodName, Me)

推荐阅读