InternetUnicodeHTMLCSSScalable Vector Graphics (SVG)Extensible Markup Language (xml) ASP.Net TOCASP.NetMiscellaneous Feature ASP.NET Scripting Visual Basic .NET TOCVB .NET Language Referencena VB.Net KeywordsVB.Net DataVB.Net Declared ElementVB.Net DelegatesVB.Net Object Characteristics Draft for Information Only
Content
VB.NET Events
VB.NET EventsWhile 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. 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 ConceptsThis section describes the terms and concepts used with events in Visual Basic. Declaring EventsYou declare events within classes, structures, modules, and interfaces using the Event keyword, as in the following example: VBEvent AnEvent(ByVal EventNumber As Integer) Raising EventsAn event is like a message announcing that something important has occurred. The act of broadcasting the message is called raising the event. In Visual Basic, you raise events with the RaiseEvent statement, as in the following example: VBRaiseEvent 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 SendersAny 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 HandlersEvent 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 uses a standard naming convention for event handlers that combines the name of the event sender, an underscore, and the name of the event. For example, the Click event of a button named button1 would be named Sub button1_Click. Note 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 HandlersBefore an event handler becomes usable, you must first associate it with an event by using either the Handles or AddHandler statement. WithEvents and the Handles ClauseThe WithEvents statement and Handles clause provide a declarative way of specifying event handlers. 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: VB' 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 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. However, be aware of the following limitations on the use of WithEvents variables:
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. 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. 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. 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: VBFriend WithEvents Button1 As System.Windows.Forms.Button Protected Sub Button1_Click() Handles Button1.Click End Sub AddHandler and RemoveHandlerThe AddHandler statement is similar to the Handles clause in that both allow you to specify an event handler. 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. If you want to handle shared events or events from a structure, you must use 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. 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: VBAddHandler Obj.XEvent, AddressOf Me.XEventHandler RemoveHandler, which disconnects an event from an event handler, uses the same syntax as AddHandler. For example: VBRemoveHandler 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. VBModule 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 ClassDerived 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
Walkthrough: Declaring and Raising EventsThis walkthrough demonstrates how to declare and raise events for a class named Widget. After you complete the steps, you might want to read the companion topic, Walkthrough: Handling Events, which shows how to use events from Widget objects to provide status information in an application. The Widget ClassAssume for the moment that you have a Widget class. Your Widget class has a method that can take a long time to execute, and you want your application to be able to put up some kind of completion indicator. Of course, you could make the Widget object show a percent-complete dialog box, but then you would be stuck with that dialog box in every project in which you used the Widget class. A good principle of object design is to let the application that uses an object handle the user interface—unless the whole purpose of the object is to manage a form or dialog box. The purpose of Widget is to perform other tasks, so it is better to add a PercentDone event and let the procedure that calls Widget's methods handle that event and display status updates. The PercentDone event can also provide a mechanism for canceling the task. To build the code example for this topic
To declare an event for the Widget class
When the calling object receives a PercentDone event, the Percent argument contains the percentage of the task that is complete. The Cancel argument can be set to True to cancel the method that raised the event. Note You can declare event arguments just as you do arguments of procedures, with the following exceptions: Events cannot have Optional or ParamArray arguments, and events do not have return values. The PercentDone event is raised by the LongTask method of the Widget class. LongTask takes two arguments: the length of time the method pretends to be doing work, and the minimum time interval before LongTask pauses to raise the PercentDone event. To raise the PercentDone event
When your application calls the LongTask method, the Widget class raises the PercentDone event every MinimumInterval seconds. When the event returns, LongTask checks to see if the Cancel argument was set to True. A few disclaimers are necessary here. For simplicity, the LongTask procedure assumes you know in advance how long the task will take. This is almost never the case. Dividing tasks into chunks of even size can be difficult, and often what matters most to users is simply the amount of time that passes before they get an indication that something is happening. You may have spotted another flaw in this sample. The Timer property returns the number of seconds that have passed since midnight; therefore, the application gets stuck if it is started just before midnight. A more careful approach to measuring time would take boundary conditions such as this into consideration, or avoid them altogether, using properties such as Now. Now that the Widget class can raise events, you can move to the next walkthrough. Walkthrough: Handling Events demonstrates how to use WithEvents to associate an event handler with the PercentDone event. See alsoWalkthrough: Handling EventsThis is the second of two topics that demonstrate how to work with events. The first topic, Walkthrough: Declaring and Raising Events, shows how to declare and raise events. This section uses the form and class from that walkthrough to show how to handle events when they take place. The Widget class example uses traditional event-handling statements. Visual Basic provides other techniques for working with events. As an exercise, you can modify this example to use the AddHandler and Handles statements. To handle the PercentDone event of the Widget class
Writing Code to Handle an EventAs soon as you declare a variable using WithEvents, the variable name appears in the left drop-down list of the class's Code Editor. When you select mWidget, the Widget class's events appear in the right drop-down list. Selecting an event displays the corresponding event procedure, with the prefix mWidget and an underscore. All the event procedures associated with a WithEvents variable are given the variable name as a prefix. To handle an event
If the user clicks the Cancel button while LongTask is running, the Button2_Click event is executed as soon as the DoEvents statement allows event processing to occur. The class-level variable mblnCancel is set to True, and the mWidget_PercentDone event then tests it and sets the ByRef Cancel argument to True. Connecting a WithEvents Variable to an ObjectForm1 is now set up to handle a Widget object's events. All that remains is to find a Widget somewhere. When you declare a variable WithEvents at design time, no object is associated with it. A WithEvents variable is just like any other object variable. You have to create an object and assign a reference to it with the WithEvents variable. To create an object and assign a reference to it
When this code executes, Visual Basic creates a Widget object and connects its events to the event procedures associated with mWidget. From that point on, whenever the Widget raises its PercentDone event, the mWidget_PercentDone event procedure is executed. To call the LongTask method
Before the LongTask method is called, the label that displays the percent complete must be initialized, and the class-level Boolean flag for canceling the method must be set to False. LongTask is called with a task duration of 12.2 seconds. The PercentDone event is raised once every one-third of a second. Each time the event is raised, the mWidget_PercentDone event procedure is executed. When LongTask is done, mblnCancel is tested to see if LongTask ended normally, or if it stopped because mblnCancel was set to True. The percent complete is updated only in the former case. To run the program
You may find it instructive to run the program with F11 and step through the code a line at a time. You can clearly see how execution enters LongTask, and then briefly re-enters Form1 each time the PercentDone event is raised. What would happen if, while execution was back in the code of Form1, the LongTask method were called again? At worst, a stack overflow might occur if LongTask were called every time the event was raised. You can cause the variable mWidget to handle events for a different Widget object by assigning a reference to the new Widget to mWidget. In fact, you can make the code in Button1_Click do this every time you click the button. To handle events for a different widget
The code above creates a new Widget each time the button is clicked. As soon as the LongTask method completes, the reference to the Widget is released, and the Widget is destroyed. A WithEvents variable can contain only one object reference at a time, so if you assign a different Widget object to mWidget, the previous Widget object's events will no longer be handled. If mWidget is the only object variable containing a reference to the old Widget, the object is destroyed. If you want to handle events from several Widget objects, use the AddHandler statement to process events from each object separately. Note You can declare as many WithEvents variables as you need, but arrays of WithEvents variables are not supported. See alsoHow to: Declare Custom Events To Avoid BlockingThere are several circumstances when it is important that one event handler not block subsequent event handlers. Custom events allow the event to call its event handlers asynchronously. By default, the backing-store field for an event declaration is a multicast delegate that serially combines all the event handlers. This means that if one handler takes a long time to complete, it blocks the other handlers until it completes. (Well-behaved event handlers should never perform lengthy or potentially blocking operations.) Instead of using the default implementation of events that Visual Basic provides, you can use a custom event to execute the event handlers asynchronously. ExampleIn this example, the AddHandler accessor adds the delegate for each handler of the Click event to an ArrayList stored in the EventHandlerList field. When code raises the Click event, the RaiseEvent accessor invokes all the event handler delegates asynchronously using the BeginInvoke method. That method invokes each handler on a worker thread and returns immediately, so handlers cannot block one another. VBPublic NotInheritable Class ReliabilityOptimizedControl 'Defines a list for storing the delegates Private EventHandlerList As New ArrayList 'Defines the Click event using the custom event syntax. 'The RaiseEvent always invokes the delegates asynchronously Public Custom Event Click As EventHandler AddHandler(ByVal value As EventHandler) EventHandlerList.Add(value) End AddHandler RemoveHandler(ByVal value As EventHandler) EventHandlerList.Remove(value) End RemoveHandler RaiseEvent(ByVal sender As Object, ByVal e As EventArgs) For Each handler As EventHandler In EventHandlerList If handler IsNot Nothing Then handler.BeginInvoke(sender, e, Nothing, Nothing) End If Next End RaiseEvent End Event End Class See alsoHow to: Declare Custom Events To Conserve MemoryThere are several circumstances when it is important that an application keep its memory usage low. Custom events allow the application to use memory only for the events that it handles. By default, when a class declares an event, the compiler allocates memory for a field to store the event information. If a class has many unused events, they needlessly take up memory. Instead of using the default implementation of events that Visual Basic provides, you can use custom events to manage the memory usage more carefully. ExampleIn this example, the class uses one instance of the EventHandlerList class, stored in the Events field, to store information about the events in use. The EventHandlerList class is an optimized list class designed to hold delegates. All events in the class use the Events field to keep track of what methods are handling each event. VBPublic Class MemoryOptimizedBaseControl ' Define a delegate store for all event handlers. Private Events As New System.ComponentModel.EventHandlerList ' Define the Click event to use the delegate store. Public Custom Event Click As EventHandler AddHandler(ByVal value As EventHandler) Events.AddHandler("ClickEvent", value) End AddHandler RemoveHandler(ByVal value As EventHandler) Events.RemoveHandler("ClickEvent", value) End RemoveHandler RaiseEvent(ByVal sender As Object, ByVal e As EventArgs) CType(Events("ClickEvent"), EventHandler).Invoke(sender, e) End RaiseEvent End Event ' Define the DoubleClick event to use the same delegate store. Public Custom Event DoubleClick As EventHandler AddHandler(ByVal value As EventHandler) Events.AddHandler("DoubleClickEvent", value) End AddHandler RemoveHandler(ByVal value As EventHandler) Events.RemoveHandler("DoubleClickEvent", value) End RemoveHandler RaiseEvent(ByVal sender As Object, ByVal e As EventArgs) CType(Events("DoubleClickEvent"), EventHandler).Invoke(sender, e) End RaiseEvent End Event ' Define additional events to use the same delegate store. ' ... End Class See alsoTroubleshooting Inherited Event Handlers in Visual BasicThis topic lists common issues that arise with event handlers in inherited components. ProceduresCode in Event Handler Executes Twice for Every Call
See also
Source/Reference
©sideway ID: 201000002 Last Updated: 10/2/2020 Revision: 0 Ref: ![]() References
![]() Latest Updated Links
![]() ![]() ![]() ![]() ![]() |
![]() Home 5 Business Management HBR 3 Information Recreation Hobbies 8 Culture Chinese 1097 English 339 Travel 18 Reference 79 Computer Hardware 254 Software Application 213 Digitization 37 Latex 52 Manim 205 KB 1 Numeric 19 Programming Web 289 Unicode 504 HTML 66 CSS 65 SVG 46 ASP.NET 270 OS 431 DeskTop 7 Python 72 Knowledge Mathematics Formulas 8 Set 1 Logic 1 Algebra 84 Number Theory 206 Trigonometry 31 Geometry 34 Calculus 67 Engineering Tables 8 Mechanical Rigid Bodies Statics 92 Dynamics 37 Fluid 5 Control Acoustics 19 Natural Sciences Matter 1 Electric 27 Biology 1 |
Copyright © 2000-2025 Sideway . All rights reserved Disclaimers last modified on 06 September 2019