我有一个活动中心,我的Winforms应用程序中的不同演示者发布事件,以便在需要时彼此通信。我相信有更好的方法可以做到这一点,但这就是我所拥有的。以下是我的问题的相关部分的片段。一切正常,除了我需要帮助创建一个通用的发布方法。我不想为Cmnd + shift + N
创建一堆重载,每个事件一个。我想要一个Sub Publish
,它可以理想地采用一种类型(或者你带来的任何东西),执行强制转换,并添加适当的处理程序。
Sub Publish
'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''” “”“”“”“”“”“”“”“”“”“”“”“”“”” '编辑:添加了一个人为的示例,显示了以下用法:
Public Delegate Sub LoginAttemptedHandler(ByVal sender As Object, ByVal e As LoginAttemptedEventArgs)
Public Class LoginAttemptedEventArgs
Inherits CustomEventArgs
Public Property BranchLocation As BranchLocation
Public Property Username As String
Public Sub New(ByVal branchLocation As BranchLocation, ByVal username As String)
Me.BranchLocation = branchLocation
Me.Username = username
EventName = "LoginAttempted"
End Sub
End Class
Public Class CustomEventArgs
Inherits EventArgs
Public Property EventName As String
End Class
public Class EventHub
Private Shared ReadOnly eventTable As New Dictionary(Of String, List(Of [Delegate]))
Public WriteOnly Property RaiseLoginAttempted As LoginAttemptedEventArgs
Set(ByVal value As LoginAttemptedEventArgs)
RaiseEvent LoginAttempted(Me, value)
End Set
End Property
Public Sub Publish(ByVal sender As Object, ByVal e As CustomEventArgs)
Dim properties As PropertyInfo() = GetType(EventHub).GetProperties
Dim count = 0
For Each p As PropertyInfo In properties
If p.Name.Contains(e.EventName) Then
p.SetValue(Me, e, Nothing)
count += 1
End If
Next
'Validate that two events were not called by accident. Each property name should contain
'the name of exaclty one event, and should correspond to exactly one event.
If count > 1 Then Throw New Exception("Two or more properties share the same event name")
End Sub
Public Sub UnRegister(ByVal handler As LoginAttemptedHandler)
RemoveHandler LoginAttempted, handler
End Sub
Public Sub Register(ByVal handler As LoginAttemptedHandler)
'AddHandler LoginAttempted, handler
'Instead of the above line, I need to make this generic to any delegate, not a specific one like LoginAttemptedHandler in this case.
End Sub
Public Custom Event LoginAttempted As LoginAttemptedHandler
AddHandler(ByVal value As LoginAttemptedHandler)
SyncLock eventTable
Dim key = "LoginAttempted"
If Not eventTable.ContainsKey(key) Then eventTable.Add(key, New List(Of [Delegate]))
eventTable(key).Add(value)
End SyncLock
End AddHandler
RemoveHandler(ByVal value As LoginAttemptedHandler)
SyncLock eventTable
eventTable("LoginAttempted").Remove(value)
End SyncLock
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As LoginAttemptedEventArgs)
Dim key = e.EventName
If eventTable.ContainsKey(key) Then
Dim delegateList = eventTable(key)
For Each handler As [Delegate] In delegateList
Dim fn = DirectCast(handler, LoginAttemptedHandler)
fn(sender, e)
Next
End If
End RaiseEvent
End Event
End Class