事件 (Visual Basic)Events (Visual Basic)

雖然您可能會將 Visual Studio 專案視覺化成一系列以序列方式執行的程式, 但實際上, 大部分的程式都是事件驅動的, 這表示執行流程是由稱為事件的外部出現專案所決定。While you might visualize a Visual Studio project as a series of procedures that execute in a sequence, in reality, most programs are event driven—meaning the flow of execution is determined by external occurrences called events.

事件是通知應用程式發生重要事件的信號。An event is a signal that informs an application that something important has occurred. 例如,當使用者按一下表單上的控制項時,表單可以引發 Click 事件,並呼叫處理事件的程序。For example, when a user clicks a control on a form, the form can raise a Click event and call a procedure that handles the event. 事件也允許個別工作進行通訊。Events also allow separate tasks to communicate. 例如,假設您的應用程式與主應用程式個別執行排序工作。Say, for example, that your application performs a sort task separately from the main application. 如果使用者取消排序,則您的應用程式可以傳送取消事件,以指示排序處理序停止。If a user cancels the sort, your application can send a cancel event instructing the sort process to stop.

事件詞彙和概念Event Terms and Concepts

本節說明 Visual Basic 中的事件所使用的詞彙和概念。This section describes the terms and concepts used with events in Visual Basic.

宣告事件Declaring Events

您可以在類別、結構、模組和介面內,使用 Event 關鍵字宣告事件,如下列範例所示:You declare events within classes, structures, modules, and interfaces using the Event keyword, as in the following example:

Event AnEvent(ByVal EventNumber As Integer)

引發事件Raising Events

事件就像是訊息,會告知發生了重要事件。An event is like a message announcing that something important has occurred. 廣播訊息的動作稱為「引發」事件。The act of broadcasting the message is called raising the event. 在 Visual Basic 中, 您會使用RaiseEvent語句引發事件, 如下列範例所示:In Visual Basic, you raise events with the RaiseEvent statement, as in the following example:

RaiseEvent AnEvent(EventNumber)

事件必須在其宣告所在的類別、模組或結構範圍內引發。Events must be raised within the scope of the class, module, or structure where they are declared. 例如,衍生的類別無法引發繼承自基底類別的事件。For example, a derived class cannot raise events inherited from a base class.

事件傳送者Event Senders

任何可引發事件的物件都是「事件傳送者」,亦稱為「事件來源」。Any object capable of raising an event is an event sender, also known as an event source. 表單、控制項和使用者定義的物件都是事件傳送者的範例。Forms, controls, and user-defined objects are examples of event senders.

事件處理常式Event Handlers

「事件處理常式」是在發生相對應事件時所呼叫的程序。Event handlers are procedures that are called when a corresponding event occurs. 您可以使用具有相符簽章的任何有效副程式,做為事件處理常式。You can use any valid subroutine with a matching signature as an event handler. 不過,您無法使用函式做為事件處理常式,因為它無法將值傳回事件來源。You cannot use a function as an event handler, however, because it cannot return a value to the event source.

Visual Basic 針對事件處理常式 (結合事件傳送者的名稱、底線和事件名稱) 使用標準命名慣例。Visual Basic uses a standard naming convention for event handlers that combines the name of the event sender, an underscore, and the name of the event. 例如,將名為 button1 的按鈕 Click 事件命名為 Sub button1_ClickFor example, the Click event of a button named button1 would be named Sub button1_Click.

注意

我們建議您在為自己的事件定義事件處理常式時,使用此命名慣例,但這並非必要;您可以使用任何有效的副程式名稱。We recommend that you use this naming convention when defining event handlers for your own events, but it is not required; you can use any valid subroutine name.

建立事件與事件處理常式的關聯Associating Events with Event Handlers

讓事件處理常式變成可用之前,您必須先使用 HandlesAddHandler 陳述式來建立它與事件的關聯。Before an event handler becomes usable, you must first associate it with an event by using either the Handles or AddHandler statement.

WithEvents 和 Handles 子句WithEvents and the Handles Clause

WithEvents 陳述式和 Handles 子句提供一種宣告式方式來指定事件處理常式。The WithEvents statement and Handles clause provide a declarative way of specifying event handlers. 使用 WithEvents 關鍵字宣告之物件所引發的事件可以透過任何具有 Handles 陳述式的程序來處理,如下列範例所示:An event raised by an object declared with the WithEvents keyword can be handled by any procedure with a Handles statement for that event, as shown in the following example:

' Declare a WithEvents variable.
Dim WithEvents EClass As New EventClass

' Call the method that raises the object's events.
Sub TestEvents()
    EClass.RaiseEvents()
End Sub

' Declare an event handler that handles multiple events.
Sub EClass_EventHandler() Handles EClass.XEvent, EClass.YEvent
    MsgBox("Received Event.")
End Sub

Class EventClass
    Public Event XEvent()
    Public Event YEvent()
    ' RaiseEvents raises both events.
    Sub RaiseEvents()
        RaiseEvent XEvent()
        RaiseEvent YEvent()
    End Sub
End Class

WithEvents 陳述式和 Handles 子句通常是事件處理常式的最佳選擇,因為它們使用的宣告式語法讓事件能夠更容易處理程式碼、讀取及偵錯。The WithEvents statement and the Handles clause are often the best choice for event handlers because the declarative syntax they use makes event handling easier to code, read and debug. 不過,請注意下列有關使用 WithEvents 變數的限制:However, be aware of the following limitations on the use of WithEvents variables:

  • 您不能使用 WithEvents 變數做為物件變數。You cannot use a WithEvents variable as an object variable. 也就是說,您無法將它宣告為 Object - 當您宣告變數時,必須指定類別名稱。That is, you cannot declare it as Object—you must specify the class name when you declare the variable.

  • 由於共用事件不會系結至類別實例, 因此您WithEvents無法使用以宣告方式處理共用事件。Because shared events are not tied to class instances, you cannot use WithEvents to declaratively handle shared events. 同樣地,您不能使用 WithEventsHandles,處理來自 Structure 的事件。Similarly, you cannot use WithEvents or Handles to handle events from a Structure. 在這兩種情況下,您可以使用 AddHandler 陳述式來處理這些事件。In both cases, you can use the AddHandler statement to handle those events.

  • 您無法建立 WithEvents 變數的陣列。You cannot create arrays of WithEvents variables.

WithEvents 變數可讓單一事件處理常式處理一或多種事件,或者讓一或多個事件處理常式處理相同種類的事件。WithEvents variables allow a single event handler to handle one or more kind of event, or one or more event handlers to handle the same kind of event.

雖然 Handles 子句是建立事件與事件處理常式之關聯的標準方式,但它只能在編譯時期建立事件與事件處理常式的關聯。Although the Handles clause is the standard way of associating an event with an event handler, it is limited to associating events with event handlers at compile time.

在某些情況下, 例如使用與表單或控制項相關聯的事件, Visual Basic 會自動將空的事件處理常式存根, 並將其與事件產生關聯。In some cases, such as with events associated with forms or controls, Visual Basic automatically stubs out an empty event handler and associates it with an event. 例如, 當您在設計模式中按兩下表單上的命令按鈕時, Visual Basic 會建立空的事件處理常式和WithEvents命令按鈕的變數, 如下列程式碼所示:For example, when you double-click a command button on a form in design mode, Visual Basic creates an empty event handler and a WithEvents variable for the command button, as in the following code:

Friend WithEvents Button1 As System.Windows.Forms.Button
Protected Sub Button1_Click() Handles Button1.Click
End Sub

AddHandler 和 RemoveHandlerAddHandler and RemoveHandler

AddHandler 陳述式類似 Handles 子句,這兩者都能讓您指定事件處理常式。The AddHandler statement is similar to the Handles clause in that both allow you to specify an event handler. 不過,與 RemoveHandler 搭配使用的 AddHandler 所提供的彈性比 Handles 子句更大,可讓您以動態方式加入、移除及變更與事件相關聯的事件處理常式。However, AddHandler, used with RemoveHandler, provides greater flexibility than the Handles clause, allowing you to dynamically add, remove, and change the event handler associated with an event. 如果您想要處理共用的事件或來自結構的事件,就必須使用 AddHandlerIf you want to handle shared events or events from a structure, you must use AddHandler.

AddHandler 會採用兩個引數︰來自事件傳送者的事件名稱 (例如控制項),以及評估委派的運算式。AddHandler takes two arguments: the name of an event from an event sender such as a control, and an expression that evaluates to a delegate. 使用 AddHandler 時,您不需明確指定委派類別,因為 AddressOf 陳述式一律會傳回對委派的參考。You do not need to explicitly specify the delegate class when using AddHandler, since the AddressOf statement always returns a reference to the delegate. 下列範例會建立事件處理常式與物件所引發之事件的關聯:The following example associates an event handler with an event raised by an object:

AddHandler Obj.XEvent, AddressOf Me.XEventHandler

RemoveHandler (其會中斷事件與事件處理常式的關聯) 會使用與 AddHandler 相同的語法。RemoveHandler, which disconnects an event from an event handler, uses the same syntax as AddHandler. 例如:For example:

RemoveHandler Obj.XEvent, AddressOf Me.XEventHandler

在下列範例中,事件處理常式會與事件相關聯,並引發事件。In the following example, an event handler is associated with an event, and the event is raised. 事件處理常式會攔截事件,並顯示一則訊息。The event handler catches the event and displays a message.

接著,移除第一個事件處理常式,並將不同的事件處理常式關聯至該事件。Then the first event handler is removed and a different event handler is associated with the event. 再次引發事件時,即會顯示不同的訊息。When the event is raised again, a different message is displayed.

最後,移除第二個事件處理常式,然後第三次引發事件。Finally, the second event handler is removed and the event is raised for a third time. 由於不再有與事件相關聯的事件處理常式,因此不會採取任何動作。Because there is no longer an event handler associated with the event, no action is taken.

Module Module1

    Sub Main()
        Dim c1 As New Class1
        ' Associate an event handler with an event.
        AddHandler c1.AnEvent, AddressOf EventHandler1
        ' Call a method to raise the event.
        c1.CauseTheEvent()
        ' Stop handling the event.
        RemoveHandler c1.AnEvent, AddressOf EventHandler1
        ' Now associate a different event handler with the event.
        AddHandler c1.AnEvent, AddressOf EventHandler2
        ' Call a method to raise the event.
        c1.CauseTheEvent()
        ' Stop handling the event.
        RemoveHandler c1.AnEvent, AddressOf EventHandler2
        ' This event will not be handled.
        c1.CauseTheEvent()
    End Sub

    Sub EventHandler1()
        ' Handle the event.
        MsgBox("EventHandler1 caught event.")
    End Sub

    Sub EventHandler2()
        ' Handle the event.
        MsgBox("EventHandler2 caught event.")
    End Sub

    Public Class Class1
        ' Declare an event.
        Public Event AnEvent()
        Sub CauseTheEvent()
            ' Raise an event.
            RaiseEvent AnEvent()
        End Sub
    End Class

End Module

處理繼承自基底類別的事件Handling Events Inherited from a Base Class

「衍生類別」(繼承基底類別特性的類別) 可以使用 Handles MyBase 陳述式,來處理其基底類別所引發的事件。Derived classes—classes that inherit characteristics from a base class—can handle events raised by their base class using the Handles MyBase statement.

處理來自基底類別的事件To handle events from a base class

  • 在衍生類別中宣告事件處理常式,方法是將 Handles MyBase.eventname 陳述式加入至事件處理常式程序的宣告行中,其中 eventname 為您要處理之基底類別中的事件名稱。Declare an event handler in the derived class by adding a Handles MyBase.eventname statement to the declaration line of your event-handler procedure, where eventname is the name of the event in the base class you are handling. 例如:For example:

    Public Class BaseClass
        Public Event BaseEvent(ByVal i As Integer)
        ' Place methods and properties here.
    End Class
    
    Public Class DerivedClass
        Inherits BaseClass
        Sub EventHandler(ByVal x As Integer) Handles MyBase.BaseEvent
            ' Place code to handle events from BaseClass here.
        End Sub
    End Class
    
標題Title 描述Description
逐步解說:宣告和引發事件Walkthrough: Declaring and Raising Events 提供如何宣告和引發類別事件的逐步說明。Provides a step-by-step description of how to declare and raise events for a class.
逐步解說:處理事件Walkthrough: Handling Events 示範如何撰寫事件處理常式的程序。Demonstrates how to write an event-handler procedure.
如何:宣告自訂事件以避免封鎖How to: Declare Custom Events To Avoid Blocking 示範如何定義自訂事件,以非同步方式呼叫它的事件處理常式。Demonstrates how to define a custom event that allows its event handlers to be called asynchronously.
如何:宣告自訂事件以節省記憶體How to: Declare Custom Events To Conserve Memory 示範如何定義只有在處理事件時才會使用記憶體的自訂事件。Demonstrates how to define a custom event that uses memory only when the event is handled.
Visual Basic 中的繼承事件處理常式疑難排解Troubleshooting Inherited Event Handlers in Visual Basic 列出繼承元件中的事件處理常式所引發的常見問題。Lists common issues that arise with event handlers in inherited components.
事件Events 提供 .NET Framework 中事件模型的概觀。Provides an overview of the event model in the .NET Framework.
在 Windows Forms 中建立事件處理常式Creating Event Handlers in Windows Forms 描述如何使用與 Windows Form 物件相關聯的事件。Describes how to work with events associated with Windows Forms objects.
委派Delegates 提供 Visual Basic 中的委派概觀。Provides an overview of delegates in Visual Basic.