尝试从 MainForm 上实例化的字典中的 Class 触发事件
Trying to fire events from a Class that is within a Dictionary instantiated on the MainForm
当此 class 在词典中时,尝试在 MainForm 中接收在 class 中引发的事件。这里有一些代码示例。
创建了 Class:
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
结束Class
在 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
如何使用作为字典一部分的 class 设置事件?
在我得到答案之前有几处错误。编写您自己的事件签名不是一个好主意。你应该使用 EventName(Sender As Object, e As ZoneEventArgs)
。如果您发现还需要其他东西,您只需要将它添加到 EventArgs
class 而不是重构代码块。为此:
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))
现在if/when你运行 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
您还应该有一个 RemoveZone
或 DropZone
方法,其中从集合中删除区域并 RemoveHandler
用于解除处理程序。
一个多更好的方法是写一个集合class。这将处理创建区域项目、在本地捕获事件并执行 DictionaryKey 的角色以便您可以找到它们。然后,当它捕获其中一个事件时,它会为表单或其他侦听器引发类似的事件。
这是一种更加灵活的方法,可以从表单中获取所有与区域相关的代码。有了字典,就没有什么可以阻止来自 adding/removing 项的其他代码 - 使用集合 class 的 OO 方法会。
当此 class 在词典中时,尝试在 MainForm 中接收在 class 中引发的事件。这里有一些代码示例。
创建了 Class:
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
结束Class
在 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
如何使用作为字典一部分的 class 设置事件?
在我得到答案之前有几处错误。编写您自己的事件签名不是一个好主意。你应该使用 EventName(Sender As Object, e As ZoneEventArgs)
。如果您发现还需要其他东西,您只需要将它添加到 EventArgs
class 而不是重构代码块。为此:
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))
现在if/when你运行 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
您还应该有一个 RemoveZone
或 DropZone
方法,其中从集合中删除区域并 RemoveHandler
用于解除处理程序。
一个多更好的方法是写一个集合class。这将处理创建区域项目、在本地捕获事件并执行 DictionaryKey 的角色以便您可以找到它们。然后,当它捕获其中一个事件时,它会为表单或其他侦听器引发类似的事件。
这是一种更加灵活的方法,可以从表单中获取所有与区域相关的代码。有了字典,就没有什么可以阻止来自 adding/removing 项的其他代码 - 使用集合 class 的 OO 方法会。