VB.NET面向对象的实现(5)事件

来源:岁月联盟 编辑:zhu 时间:2006-09-11
事件
在VB.NET中,继承是完全支持事件的。如果一个基类定义了一个Public事件,那么这个事件可以通过基类的代码或者任何由基类继承而来的子类所触发。

举个例子吧,我们可以先定义一个基类,代码如下:

Public Class Parent

Public Event ParentEvent()

Public Sub DoEvent()

RaiseEvent ParentEvent()

End Sub

End Class

很显然,类中的代码可以触发ParentEvent事件。我们还可以这样来创建一个子类:

Public Class SubClass

Inherits Parent

Public Sub DoSomething()

RaiseEvent ParentEvent()

End Sub

End Class

这个子类是通过使用Inherits关键字继承而来的,它不仅得到了父类的属性和方法,而且继承了基类的事件。

事件可以定义任何的作用域。如果定义为Private事件,那么它就只可以通过发送对象来获得,但是Public事件就可以被任何对象访问。而Protected事件可以通过定义类或者子类来创建对象进行访问。另外Friend 事件可以被VB.NET工程中的任何对象访问。本篇文章发表于

不象方法,事件不能使用Overloads关键字来进行重载。一个类可以使用任何特定的名字来定义一个事件。因为任何子类将自动从父类重得到事件,所有Override关键字就显得没什么作用,故不能用于事件中。

共享事件

事件可以定义为Shared。共享方法可以触发共享事件,而不能触发非共享事件,具体例子如下:

Public Class EventSource

Shared Event SharedEvent()

Public Shared Sub DoShared()

RaiseEvent SharedEvent()

End Sub

End Class

一个共享事件也可以由共享方法或者非共享方法来触发,下面是相应的例子:

Public Class EventSource

Public Event TheEvent()

Shared Event SharedEvent()

Public Sub DoSomething()

RaiseEvent TheEvent()

RaiseEvent SharedEvent()

End Sub

Public Shared Sub DoShared()

RaiseEvent SharedEvent()

End Sub

End Class

如果你想从一个共享方法中触发一个非共享事件就将导致一个语法错误。

在不同工程之间触发事件

在不同工程之间完成触发事件的工作,这在VB中是不能做到的。但是在VB.NET中我们可以使用Event和RaiseEvent关键字并且使用Delegate关键字来实现它。如果你想从VB.NET工程中触发一个事件并且在另外一个工程中收到这个触发,我们就必须使用事件和Delegate的概念。

执行远程事件源

当我们仍要使用RaiseEvent语句来触发事件的时候,如果要在其它VB.NET工程中的代码接收代码我们需要采用不同的方法来声明事件。特殊地,我们需要在类外部我们要触发事件的地方通过使用Delegate语句定义事件作为delegate。

接着创建一个新的类库,将它命名为EventSource并且增加一个简单类命名为RemoteClass。

假定我们想触发一个事件,这个事件返回一个字符串参数。我们首先要利用参数的类型来声明一个Delegate:

Public Delegate Sub RemoteEventHandler(ByVal SomeString As String)

通常情况下VB.NET会自动创建这个Delegate。然而,有时候这个Delegate不能从其它工程中进行访问,所以我们还是对它进行显式的声明。

以下是我们创建的类,它可以触发事件:

Public Class RemoteClass

Public Event RemoteEvent As RemoteEventHandler

Public Sub DoSomething()

RaiseEvent RemoteEvent(anyevent)

End Sub

End Class

这段功能是否成功的实现取决于事件本身的定义:

Public Event RemoteEvent As RemoteEventHandler

这个事件并没有显式地定义它的参数,而是依赖于Delegate来定义。反而,这个事件是定义为一个特殊的类型,即我们刚才定义Delegate的类型。

另外,用于触发事件的代码只是应用了一个简单的RaiseEvent语句:

RaiseEvent RemoteEvent(anyevent)

这条语句提供的参数数值用于当事件被触发时的返回值。

接收远程事件

在单一的VB.NET工程中,我们可以编写代码类接收事件。具体可以增加一个Windows应用工程来解决,你可以右击它并选择Set As Startup Project选项,这样它就可以在按F5的时候被运行了。

为了访问触发事件的类,我们必须给EventSource工程增加一个引用,具体操作如下:选择菜单项Project(工程)->Add Reference(增加引用)。

之后,我们可以增加一个按钮到窗体上,并且打开窗体的代码窗口,再引入以下的远程名空间:

Imports System.ComponentModel

Imports System.Drawing

Imports System.WinForms

Imports EventSource

在窗体A中,我们可以使用WithEvents关键字来定义远程类。

Public Class FormA

Inherits System.WinForms.Form

Private WithEvents objRemote As RemoteClass

当objRemote项在左上角的类名字下拉表中被选择的时候,我们可以在代码窗口右上角的方法名字下拉列表中看到事件的列表。当我们选择了这个选项,以下的代码就将被创建:

Public Sub objRemote_RemoteEvent() Handles objRemote.RemoteEvent

End Sub

不幸的是,这些代码是错误的,因为它没有提供我们所传递的参数。为了解决这个问题我们只需要增加参数到声明中去即可:

Public Sub objRemote_RemoteEvent(ByVal Data As String) _

Handles objRemote.RemoteEvent

Messagebox.Show(Data)

End Sub

我们还需要增加代码来在对话框中显示结果。具体做法为:增加一个按钮到窗体中去,并为按钮增加以下的代码:本篇文章发表于

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)

objRemote = New RemoteClass()

objRemote.DoSomething()

End Sub

至此我们就成功完成了从一个工程中触发事件,并且在另外一个工程中接收到这些触发的事件了。