VB.Net多项目解决方案中的事件

时间:2013-07-08 18:42:16

标签: vb.net events event-handling multi-project

是否有可能在VB.Net中的多项目解决方案中引发全局事件。例如,项目1有一个名为Form1的表单。在Form1上有一个按钮,单击该按钮时会引发一个事件,其中project2可以处理该事件,甚至project3也可以处理该事件。

2 个答案:

答案 0 :(得分:0)

您可以拥有一个专门的项目,该项目的唯一目的是举办“全球活动”。使该类实现Singleton Pattern,以便所有项目都将访问同一个实例。所有其他项目都可以参考这个项目,看起来像这样:

' This is in Project3
Public Class Class1

    Private Sub New()
    End Sub

    Private Shared _Instance As Class1

    Public Event GlobalEvent()

    Public Shared ReadOnly Property Instance As Class1
        Get
            If IsNothing(_Instance) Then
                _Instance = New Class1
            End If
            Return _Instance
        End Get
    End Property

    Public Sub RingTheBell()
        RaiseEvent GlobalEvent()
    End Sub

End Class

这是Project1中的FormA,在Project2中显示FormB(Project1引用了Project2和Project3)。我们抓住单例实例并调用RingTheBell()方法来引发“全局事件”:

' This is in Project1
Public Class FormA

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim frmB As New Project2.FormB
        frmB.Show()
    End Sub

    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        Project3.Class1.Instance.RingTheBell()
    End Sub

End Class

最后,在Project2中,我们还获取了单例实例并订阅了它的GlobalEvent(Project2只引用了Project3):

' This is in Project2
Public Class FormB

    Private WithEvents x As Project3.Class1 = Project3.Class1.Instance

    Private Sub x_GlobalEvent() Handles x.GlobalEvent
        MessageBox.Show("GlobalEvent() trapped in Project2")
    End Sub

End Class

因此,任何想要订阅“全局事件”的项目只需添加一个对Project3的引用,并使用Instance()方法返回该项目可以订阅该事件的单例实例。

答案 1 :(得分:0)

这可以通过许多可能的路线实现。在这种情况下,我更喜欢依赖注入。

首先,创建您的全局事件所有者项目。我将我的名字命名为GlobalEventSample。我删除了默认命名空间并在此明确声明它以使代码结构更加明显:

Namespace GlobalEventSample

    Public Module Module1

        Public Event GlobalEvent As EventHandler

        Public Sub Main()

            Console.WriteLine("Press any key to raise event...")
            Console.ReadKey(True)

            RaiseEvent GlobalEvent(Nothing, EventArgs.Empty)

            Console.WriteLine("Press any key to quit...")
            Console.ReadKey(True)

        End Sub

    End Module

End Namespace

现在创建一个消费者项目。我将我的名字命名为GlobalEventConsumer。我删除了默认命名空间并在此处明确声明(如上所述):

Namespace GlobalEventConsumer

    Public Interface IGlobalEventOwner

        Event GlobalEvent As EventHandler

    End Interface

    Public Class Class1

        Public Sub New(ByVal globalEvent As IGlobalEventOwner)
            AddHandler globalEvent.GlobalEvent, AddressOf GlobalEventHandler
        End Sub

        Public Shared Sub GlobalEventHandler(ByVal sender As Object, ByVal e As EventArgs)
            Console.WriteLine("Event Handled!")
        End Sub

    End Class

End Namespace

请注意,我已经声明了一个名为“IGlobalEventOwner”的接口。它所做的就是用事件定义一个对象。此事件的签名与我们要处理的全局事件相同。

返回示例项目并创建对使用者项目的引用。

使用者项目需要一个实现IGlobalEventOwner的对象。模块无法实现接口,因此我们创建一个私有类GlobalEventRouter,它将简单地处理模块的事件,然后触发它自己的事件。最后,我们将在Main子类中创建一个新的Class 1实例,并传递一个GlobalEventRouter类的实例。

Namespace GlobalEventSample

    Public Module Module1

        Public Event GlobalEvent As EventHandler

        Public Sub Main()

            Dim consumer As New GlobalEventConsumer.Class1(New GlobalEventRouter())

            Console.WriteLine("Press any key to raise event...")
            Console.ReadKey(True)

            RaiseEvent GlobalEvent(Nothing, EventArgs.Empty)

            Console.WriteLine("Press any key to quit...")
            Console.ReadKey(True)

        End Sub

        Private Class GlobalEventRouter
            Implements GlobalEventConsumer.IGlobalEventOwner

            Public Event GlobalEvent(ByVal sender As Object, ByVal e As System.EventArgs) Implements GlobalEventConsumer.IGlobalEventOwner.GlobalEvent

            Public Sub New()
                AddHandler Module1.GlobalEvent, AddressOf GlobalEventHandler
            End Sub

            Private Sub GlobalEventHandler(ByVal sender As Object, ByVal e As EventArgs)
                RaiseEvent GlobalEvent(sender, e)
            End Sub

        End Class

    End Module

End Namespace

输出:

  

按任意键举起事件......
  事件处理!
  按任意键退出...