Trying to have events raised within a class be received within the MainForm when this class is within a Dictionary. Here are some code samples.
Created a 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
End Class
Within the FormMain code we have:
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
How do I setup events from with the class that is part of a dictionary?
There are several things wrong before I can get to an answer. It is not a good idea to make up you own Event signature. You should use EventName(Sender As Object, e As ZoneEventArgs)
. If you discover that something else is needed in the event you just need to add it to the EventArgs
class rather than refactor gobs of code. For that:
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))
Now if/when you run CA, it wont scold you...at least not for that.
Declaring the Dictionary in FormLoad is bad because it will only exist there, but I'll assume that is an artifact of being a demo. To keep it like that, each item added to the collection needs to be hooked up to an event handler. For that, you need there to be only one way in and one way out of the 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
You should also have a RemoveZone
or DropZone
method where the zones are removed from the collection and RemoveHandler
used to unhook the handler.
A much better way is to write a collection class. This would handle creating Zone items, catch the events locally and perform the role of the DictionaryKey to you can find them. Then when it catches one of those events, it Raises a similar one for the form or other listeners.
Its a much more flexible approach and gets all the Zone related code out of the form. With the Dictionary the way it is there is, there is nothing to stop other code from adding/removing items - an OO approach using a collection class would.