0

来自 Deplhi,我习惯于使用简单的方法直接从实例调用事件处理程序

Button.OnMouseOver([arguments])

现在我在 VB.NET 上,我找不到在没有实际触发事件的情况下触发事件处理程序的方法。

对我在这里所做的一些解释:在创建新表单时,我解析其内容以根据变量设置所有颜色。根据按钮是否启用,它有不同的颜色,但如果按钮在创建时被禁用,它仍然需要通过处理程序来校正其颜色。

这就是我正在使用的

AddHandler ButtonInstance.EnabledChanged, AddressOf Button_EnabledChanged
Button_EnabledChanged(ButtonInstance, New EventArgs)

这可以正常工作,但我仍然希望能够直接从它正在处理的对象调用该方法,只是因为我并不总是事先知道事件处理程序的名称。

我一直被指向 RaiseEvent,但它似乎没有做我需要的事情。

有没有办法在不实际干扰实例的情况下检索事件处理程序或触发它?

4

2 回答 2

0

在不触发事件本身的情况下调用事件处理程序有什么意义?

如果您在代码中定义了事件,则可以使用 触发它RaiseEvent EventName,但这不是EnabledChanged因为它是在基类中定义的。您还可以在其名称中添加 Event 后缀以使用它的处理程序等,例如EventNameEvent.GetInvocationList

如果您的事件是在您无法修改的基类中声明的,您可以继承该类并调用 OnEventName 方法,该方法应触发该事件并调用所有处理程序。OnEventName 方法的实际实现可以防止事件被触发。这取决于基类的实现。

手动查找和触发继承事件的事件处理程序需要反射。

于 2018-06-01T12:59:37.573 回答
0

简单回答是不。我确信在技术上可以使用反射来获取已添加到事件中的代表列表并调用每个代表,但这将是一个丑陋的 hack,只应在最绝望的情况下使用。如果您需要这样做,VB.NET 中的最佳方法是设置一个事件处理程序,该处理程序总是在引发事件时被调用(这样您也可以自己直接调用它),然后包含一个委托列表然后它依次调用。换句话说,使用委托来创建您自己的类似事件的机制,从而提供您需要的灵活性。例如,像这样:

Private _clickActions As New List(Of Action)()

Public Sub AddClickAction(action As Action)
    _clickActions.Add(action)
End Sub

Public Sub PerformClickActions()
    For Each action As Action in _clickActions
        action?.Invoke()
    Next
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs)
    PerformClickActions()
End Sub

如果您需要在多个地方使用不同类型的事件来执行此操作,那么为这种事情创建一个通用的通用类似乎很容易。

于 2018-06-01T13:17:53.193 回答