1

当此类在字典中时,尝试在 MainForm 中接收在类中引发的事件。以下是一些代码示例。

创建了一个类:

Public Class Zone
Public _ZoneID As Integer
Public _ZoneName As String

Public Event ZoneEntered(ByVal intToolID As Integer, ByVal intZoneID As Integer)

Public Sub New()

End Sub

Public Property ZoneName() As String
    Get
        Return _ZoneName
    End Get
    Set(value As String)
        _ZoneName = value
    End Set
End Property

Public Property ZoneID() As Integer
    Get
        Return _ZoneID
    End Get
    Set(value As Integer)
        _ZoneID = value
    End Set
End Property

Public Sub CheckZone(ByVal intToolID As Integer)
    If intToolID > 0 Then
        RaiseEvent ZoneEntered(intToolID, _ZoneID)
    End If
End Sub

结束类

在 FormMain 代码中,我们有:

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim Zones As New Dictionary(Of Integer, Zone) 'Holds all the Zones for all CameraGroups within this Workspace

    Dim NewZone As Zone
    NewZone.ZoneName = "TestZone"
    NewZone.ZoneID = 123
    Zones.Add(1, NewZone)

    Dim intZoneID As Integer = 1
    If Zones.ContainsKey(intZoneID) Then
        Dim ZoneActive As Zone
        ZoneActive = Zones(intZoneID)
        If Not (ZoneActive Is Nothing) Then
            ZoneActive.CheckZone(intZoneID) 'This would fire the event I am looking for
        End If
    End If

End Sub

如何使用作为字典一部分的类设置事件?

4

1 回答 1

2

在我得到答案之前,有几件事是错误的。编写自己的事件签名不是一个好主意。你应该使用EventName(Sender As Object, e As ZoneEventArgs). 如果您发现在事件中需要其他东西,您只需将其添加到EventArgs类中而不是重构代码块。为了那个原因:

Public Class ZoneEventArgs
    Inherits EventArgs

    Public Property ToolID As Integer
    Public Property ZoneID As Integer

    Public Sub New(tool As Integer, zone As Integer)
       ToolID = tool
       ZoneID = zone
    End Sub
End Class

' event sig:
Public Event ZoneEntered(sender As Object, e As ZoneEventArgs)

' raise it:
RaiseEvent ZoneEntered(Me, New ZoneEventArgs(thisTool, thisZone))

现在,如果/当您运行 CA 时,它不会责骂您……至少不会因此而责骂您。

在 FormLoad 中声明 Dictionary 是不好的,因为它只会存在于那里,但我会假设这是一个演示的工件。为了保持这种状态,添加到集合中的每个项目都需要连接到事件处理程序。为此,您需要只有一种进入和退出字典的方式:

Friend Sub AddZone(name As String, zID as Integer, key As Integer)

    Dim z As New Zone With {.ZoneName = name, .ZoneID = zID)
    AddHandler z.ZoneEntered, AddressOf NewZoneEntered
    Zones.Add(key, z)
End Sub  

Private Sub NewZoneEntered(sender As Object, e As ZoneEventArgs)
    ' respond
End Sub

您还应该有一个RemoveZoneorDropZone方法,将区域从集合中删除并RemoveHandler用于解开处理程序。

一个更好的方法是编写一个集合类。这将处理创建区域项目,在本地捕获事件并执行 DictionaryKey 的角色,以便您可以找到它们。然后,当它捕获其中一个事件时,它会为表单或其他侦听器引发类似的事件。

它是一种更加灵活的方法,并且可以将所有与 Zone 相关的代码从表格中删除。使用 Dictionary 的方式,没有什么可以阻止其他代码添加/删除项目 - 使用集合类的 OO 方法可以。

于 2015-06-02T16:29:46.573 回答