尝试从MainForm上实例化的Dictionary中的Class中触发事件

时间:2015-06-01 20:48:48

标签: vb.net class events dictionary raiseevent

当此类在Dictionary中时,尝试在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

如何使用属于字典的类来设置事件?

1 个答案:

答案 0 :(得分:1)

在我得到答案之前,有几件事情是错误的。组建自己的事件签名并不是一个好主意。您应该使用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中声明字典是不好的,因为它只存在于那里,但我认为这是一个演示的工件。为了保持这种状态,添加到集合中的每个项目都需要连接到事件处理程序。为此,你需要只有一种方式进入字典:

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

您还应该使用RemoveZoneDropZone方法从集合中删除区域,并使用RemoveHandler取消处理程序。

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

它是一种更灵活的方法,可以从表单中获取所有与区域相关的代码。随着字典的存在方式,没有什么可以阻止其他代码添加/删除项目 - 使用集合类的OO方法会。