在VB.NET中记录和重放引发的事件

3
我使用VB.NET中的事件实现了两个类之间的通信。现在我想记录所有发生的事件并在以后重新触发它们。以下是我的实现:
Class1:
Public Event Button1Pressed(ByVal sender As Object)

Private Sub btnButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnButton.Click
    RaiseEvent Button1Pressed(Me)
End Sub

Public Sub handleDisplayChanged(ByVal sender As System.Object, ByVal txt As String)

        '... Some code
End Sub

第二类:

Public Event DisplayTextChangedEvent(ByVal sender As System.Object, ByVal text As String)

'In the constructor:
AddHandler Me.DisplayTextChangedEvent, AddressOf class1Instance.displayText
AddHandler class1Instance.Button1Pressed, AddressOf Me.buttonPressed

'Somewhere in the logic:
Public Sub buttonPressed(ByVal sender As Object)

    'Compute text
    '...
    RaiseEvent DisplayTextChangedEvent(text)
End Sub

我可以为我想要记录的事件添加另一个处理程序,但是在处理程序中,我只能获得传递给事件的参数,而不能获取事件本身。另外一件我不知道如何解决的事情是,我无法从外部类触发事件。

有没有解决我的问题的好方法?

1个回答

0

为了记录事件,您可以创建一个辅助方法来同时进行记录和触发。因此,不要这样做:

RaiseEvent Button1Pressed(Me)

做这个:
Sub RaiseButton1PressedEvent()
  RaiseEvent Button1Pressed(Me)  <--raise the event

  RecordEvent("Button1Pressed")  <--record the event
End Sub

RecordEvent的功能必须经过设计。

要从外部类中引发事件,请实现此方法:

Sub ReplayButton1PressedEvent()
  RaiseEvent Button1Pressed(Me)  <--raise the event
End Sub

现在,如果你有很多事件,这可能会变得乏味。有几种不错的方法可以解决这个问题:

  1. 可能有一种使用反射来触发事件的方法,基于事件名称,因此您可以实现一个通用函数而不是每个事件一个函数,即:代替 Sub RaiseButton1PressedEvent(),您可以有一个 Sub RaiseEventByName(sEventName As String)

  2. 使用代码生成来发出部分类,其中包含要跟踪的每个事件的Raise和Replay方法。


谢谢您的回答。我原本希望有一种更优雅的解决方案,但也许这是唯一的方法。 - steckl
你知道 Visual Studio 内置的 T4 模板系统吗?它使得代码生成变得非常容易。我经常在需要生成许多类似但不完全相同的方法时使用它。例如,这就是如何创建类型化数据集和 LinqToEntities 实体类的。这是一个完全合理的做法。 - Joshua Frank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接