Event 语句Event Statement

声明用户定义的事件。Declares a user-defined event.


[ <attrlist> ] [ accessmodifier ] _  
[ Shared ] [ Shadows ] Event eventname[(parameterlist)] _  
[ Implements implementslist ]  
' -or-  
[ <attrlist> ] [ accessmodifier ] _  
[ Shared ] [ Shadows ] Event eventname As delegatename _  
[ Implements implementslist ]  
' -or-  
 [ <attrlist> ] [ accessmodifier ] _  
[ Shared ] [ Shadows ] Custom Event eventname As delegatename _  
[ Implements implementslist ]  
   [ <attrlist> ] AddHandler(ByVal value As delegatename)  
      [ statements ]  
   End AddHandler  
   [ <attrlist> ] RemoveHandler(ByVal value As delegatename)  
      [ statements ]  
   End RemoveHandler  
   [ <attrlist> ] RaiseEvent(delegatesignature)  
      [ statements ]  
   End RaiseEvent  
End Event  


部件Part 说明Description
attrlist 可选。Optional. 应用于此事件的特性列表。List of attributes that apply to this event. 用逗号分隔多个属性。Multiple attributes are separated by commas. 必须将属性列表用尖括号括起来("<" 和 ">")。You must enclose the Attribute List in angle brackets ("<" and ">").
accessmodifier 可选。Optional. 指定哪些代码可以访问事件。Specifies what code can access the event. 可以是以下各项之一:Can be one of the following:

- Public—可以访问声明它的元素的任何代码都可以访问它。- Public—any code that can access the element that declares it can access it.
- 保护-只有其类或派生类中的代码可以访问它。- Protected—only code within its class or a derived class can access it.
- 朋友—只有同一程序集中的代码才能访问它。- Friend—only code in the same assembly can access it.
- Private—只有声明它的元素中的代码才能访问它。- Private—only code in the element that declares it can access it.
在事件的类、派生类或同一程序集内 - 受保护的仅限 Friend 的代码可以访问。- Protected Friend-only code in the event's class, a derived class, or the same assembly can access it.
在事件的类中,或在同一程序集中的派生类 - 仅限私有保护的代码。- Private Protected-only code in the event's class or a derived class in the same assembly can access it.
Shared 可选。Optional. 指定此事件不与类或结构的特定实例关联。Specifies that this event is not associated with a specific instance of a class or structure.
Shadows 可选。Optional. 指示此事件重新声明并隐藏基类中具有相同名称的编程元素(或重载元素集)。Indicates that this event redeclares and hides an identically named programming element, or set of overloaded elements, in a base class. 可以与任何其他类型一起隐藏任何类型的已声明元素。You can shadow any kind of declared element with any other kind.

隐藏的元素不可在隐藏它的派生类中使用(除了从隐藏元素不可访问的位置)。A shadowed element is unavailable from within the derived class that shadows it, except from where the shadowing element is inaccessible. 例如,如果 Private 元素隐藏一个基类元素,则无权访问 Private 元素的代码会改为访问该基类元素。For example, if a Private element shadows a base-class element, code that does not have permission to access the Private element accesses the base-class element instead.
eventname 必需。Required. 事件的名称;遵循标准变量命名约定。Name of the event; follows standard variable naming conventions.
parameterlist 可选。Optional. 表示此事件的参数的本地变量列表。List of local variables that represent the parameters of this event. 必须将参数列表括在括号中。You must enclose the Parameter List in parentheses.
Implements 可选。Optional. 指示此事件实现接口的事件。Indicates that this event implements an event of an interface.
implementslist 如果提供 Implements,则是必需的。Required if Implements is supplied. 所实现的 Sub 过程的列表。List of Sub procedures being implemented. 用逗号分隔多个过程:Multiple procedures are separated by commas:

implementedprocedure [, implementedprocedure ...]implementedprocedure [ , implementedprocedure ... ]

每个 implementedprocedure 都具有以下语法和部件:Each implementedprocedure has the following syntax and parts:


- interface-必需。- interface - Required. 此过程的包含类或结构所实现的接口的名称。Name of an interface that this procedure's containing class or structure is implementing.
- Definedname-必需。- Definedname - Required. interface 中用于定义过程的名称。Name by which the procedure is defined in interface. 这不必与 name(此过程用于实现定义的过程的名称)相同。This does not have to be the same as name, the name that this procedure is using to implement the defined procedure.
Custom 必需。Required. 声明为 Custom 的事件必须定义自定义 AddHandlerRemoveHandlerRaiseEvent 访问器。Events declared as Custom must define custom AddHandler, RemoveHandler, and RaiseEvent accessors.
delegatename 可选。Optional. 指定事件处理程序签名的委托的名称。The name of a delegate that specifies the event-handler signature.
AddHandler 必需。Required. 声明 AddHandler 访问器,它指定要在添加事件处理程序(显式使用 AddHandler 语句或隐式使用 Handles 子句)时执行的语句。Declares an AddHandler accessor, which specifies the statements to execute when an event handler is added, either explicitly by using the AddHandler statement or implicitly by using the Handles clause.
End AddHandler 必需。Required. 终止 AddHandler 块。Terminates the AddHandler block.
value 必需。Required. 参数名称。Parameter name.
RemoveHandler 必需。Required. 声明 RemoveHandler 访问器,它指定要在使用 RemoveHandler 语句移除事件处理程序时执行的语句。Declares a RemoveHandler accessor, which specifies the statements to execute when an event handler is removed using the RemoveHandler statement.
End RemoveHandler 必需。Required. 终止 RemoveHandler 块。Terminates the RemoveHandler block.
RaiseEvent 必需。Required. 声明 RaiseEvent 访问器,它指定要在使用 RaiseEvent 语句引发事件时执行的语句。Declares a RaiseEvent accessor, which specifies the statements to execute when the event is raised using the RaiseEvent statement. 通常这会调用由 AddHandlerRemoveHandler 访问器维护的委托的列表。Typically, this invokes a list of delegates maintained by the AddHandler and RemoveHandler accessors.
End RaiseEvent 必需。Required. 终止 RaiseEvent 块。Terminates the RaiseEvent block.
delegatesignature 必需。Required. delegatename 委托需要的参数匹配的参数列表。List of parameters that matches the parameters required by the delegatename delegate. 必须将参数列表括在括号中。You must enclose the Parameter List in parentheses.
statements 可选。Optional. 包含 AddHandlerRemoveHandlerRaiseEvent 方法体的语句。Statements that contain the bodies of the AddHandler, RemoveHandler, and RaiseEvent methods.
End Event 必需。Required. 终止 Event 块。Terminates the Event block.


一旦声明了事件,便可使用 RaiseEvent 语句引发事件。Once the event has been declared, use the RaiseEvent statement to raise the event. 可以按以下片段所示声明和引发典型事件:A typical event might be declared and raised as shown in the following fragments:

Public Class EventSource
    ' Declare an event.
    Public Event LogonCompleted(ByVal UserName As String)
    Sub CauseEvent()
        ' Raise an event on successful logon.
        RaiseEvent LogonCompleted("AustinSteele")
    End Sub
End Class


可以正如处理过程的自变量一样来声明事件自变量,不过有以下例外:事件不能具有命名自变量、ParamArray 自变量或 Optional 自变量。You can declare event arguments just as you do arguments of procedures, with the following exceptions: events cannot have named arguments, ParamArray arguments, or Optional arguments. 事件没有返回值。Events do not have return values.

若要处理事件,必须使用 HandlesAddHandler 语句将它与事件处理程序子例程关联。To handle an event, you must associate it with an event handler subroutine using either the Handles or AddHandler statement. 子例程和事件的签名必须匹配。The signatures of the subroutine and the event must match. 若要处理共享事件,必须使用 AddHandler 语句。To handle a shared event, you must use the AddHandler statement.

只能在模块级别使用 EventYou can use Event only at module level. 这意味着,事件的声明上下文必须是类、结构、模块或接口,不能是源文件、命名空间、过程或块。This means the declaration context for an event must be a class, structure, module, or interface, and cannot be a source file, namespace, procedure, or block. 有关详细信息,请参阅声明上下文和默认访问级别For more information, see Declaration Contexts and Default Access Levels.

在大多数情况下,可以使用本主题的“语法”部分中的第一个语法来声明事件。In most circumstances, you can use the first syntax in the Syntax section of this topic for declaring events. 但是,某些情况要求更好地控制事件的详细行为。However, some scenarios require that you have more control over the detailed behavior of the event. 使用本主题“语法”部分中的最后一个语法(该语法使用 Custom 关键字)可通过使你可以定义自定义事件来提供这种控制。The last syntax in the Syntax section of this topic, which uses the Custom keyword, provides that control by enabling you to define custom events. 在自定义事件中,可精确地指定在代码对事件添加或移除事件处理程序时,或是代码引发事件时发生的情况。In a custom event, you specify exactly what occurs when code adds or removes an event handler to or from the event, or when code raises the event. 有关示例,请参阅如何:声明自定义事件以节省内存如何:声明自定义事件以避免阻止For examples, see How to: Declare Custom Events To Conserve Memory and How to: Declare Custom Events To Avoid Blocking.


下面的示例使用事件从 10 秒到 0 秒进行倒计时。The following example uses events to count down seconds from 10 to 0. 代码演示了几个与事件相关的方法、属性和语句。The code illustrates several of the event-related methods, properties, and statements. 这包括 RaiseEvent 语句。This includes the RaiseEvent statement.

引发事件的类是事件源,处理事件的方法是事件处理程序。The class that raises an event is the event source, and the methods that process the event are the event handlers. 事件源对于它生成的事件可以具有多个处理程序。An event source can have multiple handlers for the events it generates. 类引发事件时,会在选择用于为对象的该实例处理事件的每个类上引发该事件。When the class raises the event, that event is raised on every class that has elected to handle events for that instance of the object.

该示例还使用一个窗体 (Form1),其中包含一个按钮 (Button1) 和一个文本框 (TextBox1)。The example also uses a form (Form1) with a button (Button1) and a text box (TextBox1). 单击该按钮时,第一个文本框显示从 10 秒到 0 秒的倒计时。When you click the button, the first text box displays a countdown from 10 to 0 seconds. 经过了全部时间(10 秒)之后,第一个文本框会显示“Done”。When the full time (10 seconds) has elapsed, the first text box displays "Done".

Form1 的代码指定窗体的初始和最终状态。The code for Form1 specifies the initial and terminal states of the form. 它还包含引发事件时执行的代码。It also contains the code executed when events are raised.

若要使用此示例,请打开新的 Windows 窗体项目。To use this example, open a new Windows Forms project. 然后向名为 Button1 的主窗体添加一个名为 TextBox1 的按钮和一个名为 Form1 的文本框。Then add a button named Button1 and a text box named TextBox1 to the main form, named Form1. 然后,右键单击该窗体,然后单击 "查看代码" 以打开代码编辑器。Then right-click the form and click View Code to open the code editor.

WithEvents 类的声明部分添加一个 Form1 变量:Add a WithEvents variable to the declarations section of the Form1 class:

Private WithEvents mText As TimerState

将下面的代码添加到 Form1 的代码:Add the following code to the code for Form1. 替换可能存在的任何重复过程,如 Form_LoadButton_ClickReplace any duplicate procedures that may exist, such as Form_Load or Button_Click.

Private Sub Form1_Load() Handles MyBase.Load
    Button1.Text = "Start"
    mText = New TimerState
End Sub
Private Sub Button1_Click() Handles Button1.Click
    mText.StartCountdown(10.0, 0.1)
End Sub

Private Sub mText_ChangeText() Handles mText.Finished
    TextBox1.Text = "Done"
End Sub

Private Sub mText_UpdateTime(ByVal Countdown As Double
  ) Handles mText.UpdateTime

    TextBox1.Text = Format(Countdown, "##0.0")
    ' Use DoEvents to allow the display to refresh.
End Sub

Class TimerState
    Public Event UpdateTime(ByVal Countdown As Double)
    Public Event Finished()
    Public Sub StartCountdown(ByVal Duration As Double, 
                              ByVal Increment As Double)
        Dim Start As Double = DateAndTime.Timer
        Dim ElapsedTime As Double = 0

        Dim SoFar As Double = 0
        Do While ElapsedTime < Duration
            If ElapsedTime > SoFar + Increment Then
                SoFar += Increment
                RaiseEvent UpdateTime(Duration - SoFar)
            End If
            ElapsedTime = DateAndTime.Timer - Start
        RaiseEvent Finished()
    End Sub
End Class

按 F5 运行前面的示例,并单击标签为 "启动" 的按钮。Press F5 to run the previous example, and click the button labeled Start. 第一个文本框中开始倒计时秒数。The first text box starts to count down the seconds. 经过了全部时间(10 秒)之后,第一个文本框会显示“Done”。When the full time (10 seconds) has elapsed, the first text box displays "Done".


My.Application.DoEvents 方法不会按照与窗体相同的方式来处理事件。The My.Application.DoEvents method does not process events in the same way the form does. 若要使窗体可以直接处理事件,可以使用多线程处理。To enable the form to handle the events directly, you can use multithreading. 有关详细信息,请参阅托管线程处理For more information, see Managed Threading.

另请参阅See also