Sideway
output.to from Sideway
Draft for Information Only

Content

VB.NET Events
 Event Terms and Concepts
  Declaring Events
  Raising Events
  Event Senders
  Event Handlers
 Associating Events with Event Handlers
  WithEvents and the Handles Clause
  AddHandler and RemoveHandler
 Handling Events Inherited from a Base Class
  To handle events from a base class
 Walkthrough: Declaring and Raising Events
 The Widget Class
   To build the code example for this topic
   To declare an event for the Widget class
   To raise the PercentDone event
 See also
 Walkthrough: Handling Events
  To handle the PercentDone event of the Widget class
 Writing Code to Handle an Event
   To handle an event
 Connecting a WithEvents Variable to an Object
   To create an object and assign a reference to it
   To call the LongTask method
   To run the program
   To handle events for a different widget
 See also
 How to: Declare Custom Events To Avoid Blocking
 Example
 See also
 How to: Declare Custom Events To Conserve Memory
  
 Example
 See also
  Troubleshooting Inherited Event Handlers in Visual Basic
 Procedures
   Code in Event Handler Executes Twice for Every Call
 See also
  Source/Reference

VB.NET Events

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. 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

This section describes the terms and concepts used with events in Visual Basic.

Declaring Events

You declare events within classes, structures, modules, and interfaces using the Event keyword, as in the following example:

VB
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. In Visual Basic, you raise events with the RaiseEvent statement, as in the following example:

VB
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 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 Handlers

Before 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 Clause

The 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:

  • You cannot use a WithEvents variable as an object variable. That is, you cannot declare it as Object—you must specify the class name when you declare the variable.

  • Because shared events are not tied to class instances, you cannot use WithEvents to declaratively handle shared events. Similarly, you cannot use WithEvents or Handles to handle events from a Structure. In both cases, you can use the AddHandler statement to handle those events.

  • You cannot create arrays 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:

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

AddHandler and RemoveHandler

The 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:

VB
AddHandler Obj.XEvent, AddressOf Me.XEventHandler

RemoveHandler, which disconnects an event from an event handler, uses the same syntax as AddHandler. For example:

VB
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.

VB
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

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

  • 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:

    VB
  • 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
    

Walkthrough: Declaring and Raising Events

This 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 Class

Assume 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

  1. Open a new Visual Basic Windows Application project and create a form named Form1.

  2. Add two buttons and a label to Form1.

  3. Name the objects as shown in the following table.

    Object Property Setting
    Button1 Text Start Task
    Button2 Text Cancel
    Label (Name), Text lblPercentDone, 0
  4. On the Project menu, choose Add Class to add a class named Widget.vb to the project.

To declare an event for the Widget class

  • Use the Event keyword to declare an event in the Widget class. Note that an event can have ByVal and ByRef arguments, as Widget's PercentDone event demonstrates:

    VB
  • Public Event PercentDone(ByVal Percent As Single, 
                             ByRef Cancel As Boolean)
    

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

  1. To simplify access to the Timer property used by this class, add an Imports statement to the top of the declarations section of your class module, above the Class Widget statement.

    VB
    Imports Microsoft.VisualBasic.DateAndTime
    
  2. Add the following code to the Widget class:

    VB
    Public Sub LongTask(ByVal Duration As Single, 
                        ByVal MinimumInterval As Single)
        Dim Threshold As Single
        Dim Start As Single
        Dim blnCancel As Boolean
    
        ' The Timer property of the DateAndTime object returns the seconds
        ' and milliseconds that have passed since midnight.
        Start = CSng(Timer)
        Threshold = MinimumInterval
    
        Do While CSng(Timer) < (Start + Duration)
            ' In a real application, some unit of work would
            ' be done here each time through the loop.
            If CSng(Timer) > (Start + Threshold) Then
                RaiseEvent PercentDone( 
                Threshold / Duration, blnCancel)
                ' Check to see if the operation was canceled.
                If blnCancel Then Exit Sub
                Threshold = Threshold + MinimumInterval
            End If
        Loop
    End Sub
    

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 also

Walkthrough: Handling Events

This 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

  1. Place the following code in Form1:

    VB
  1. Private WithEvents mWidget As Widget
    Private mblnCancel As Boolean
    

    The WithEvents keyword specifies that the variable mWidget is used to handle an object's events. You specify the kind of object by supplying the name of the class from which the object will be created.

    The variable mWidget is declared in Form1 because WithEvents variables must be class-level. This is true regardless of the type of class you place them in.

    The variable mblnCancel is used to cancel the LongTask method.

Writing Code to Handle an Event

As 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

  1. Select mWidget from the left drop-down list in the Code Editor.

  2. Select the PercentDone event from the right drop-down list. The Code Editor opens the mWidget_PercentDone event procedure.

    Note

    The Code Editor is useful, but not required, for inserting new event handlers. In this walkthrough, it is more direct to just copy the event handlers directly into your code.

  3. Add the following code to the mWidget_PercentDone event handler:

    VB
    Private Sub mWidget_PercentDone( 
        ByVal Percent As Single, 
        ByRef Cancel As Boolean 
    ) Handles mWidget.PercentDone
        lblPercentDone.Text = CInt(100 * Percent) & "%"
        My.Application.DoEvents()
        If mblnCancel Then Cancel = True
    End Sub
    

    Whenever the PercentDone event is raised, the event procedure displays the percent complete in a Label control. The DoEvents method allows the label to repaint, and also gives the user the opportunity to click the Cancel button.

  4. Add the following code for the Button2_Click event handler:

    VB
    Private Sub Button2_Click( 
        ByVal sender As Object, 
        ByVal e As System.EventArgs 
    ) Handles Button2.Click
        mblnCancel = True
    End Sub
    

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 Object

Form1 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

  1. Select (Form1 Events) from the left drop-down list in the Code Editor.

  2. Select the Load event from the right drop-down list. The Code Editor opens the Form1_Load event procedure.

  3. Add the following code for the Form1_Load event procedure to create the Widget:

    VB
  1. Private Sub Form1_Load( 
        ByVal sender As System.Object, 
        ByVal e As System.EventArgs 
    ) Handles MyBase.Load
        mWidget = New Widget
    End Sub
    

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

  • Add the following code to the Button1_Click event handler:

    VB
  • Private Sub Button1_Click( 
        ByVal sender As Object, 
        ByVal e As System.EventArgs 
    ) Handles Button1.Click
        mblnCancel = False
        lblPercentDone.Text = "0%"
        lblPercentDone.Refresh()
        mWidget.LongTask(12.2, 0.33)
        If Not mblnCancel Then lblPercentDone.Text = CStr(100) & "%"
    End Sub
    

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

  1. Press F5 to put the project in run mode.

  2. Click the Start Task button. Each time the PercentDone event is raised, the label is updated with the percentage of the task that is complete.

  3. Click the Cancel button to stop the task. Notice that the appearance of the Cancel button does not change immediately when you click it. The Click event cannot happen until the My.Application.DoEvents statement allows event processing.

    Note

    The My.Application.DoEvents method does not process events in exactly the same way as the form does. For example, in this walkthrough, you must click the Cancel button twice. To allow the form to handle the events directly, you can use multithreading. For more information, see Managed Threading.

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

  • Add the following line of code to the Button1_Click procedure, immediately preceding the line that reads mWidget.LongTask(12.2, 0.33):

    VB
  • mWidget = New Widget
    ' Create a new Widget object.
    

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 also

How to: Declare Custom Events To Avoid Blocking

There 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.

Example

In 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.

VB
Public 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 also

How to: Declare Custom Events To Conserve Memory

 

There 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.

Example

In 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.

VB
Public 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 also

Troubleshooting Inherited Event Handlers in Visual Basic

This topic lists common issues that arise with event handlers in inherited components.

Procedures

Code in Event Handler Executes Twice for Every Call

  • An inherited event handler must not include a Handles clause. The method in the base class is already associated with the event and will fire accordingly. Remove the Handles clause from the inherited method.

    VB
  • ' INCORRECT
    Protected Overrides Sub Button1_Click( 
        ByVal sender As System.Object, 
        ByVal e As System.EventArgs) Handles Button1.Click
    
        ' The Handles clause will cause all code
        ' in this block to be executed twice.
    End Sub
    
  • If the inherited method does not have a Handles keyword, verify that your code does not contain an extra AddHandler Statement or any additional methods that handle the same event.

See also

 

Source/Reference

 


©sideway

ID: 201000002 Last Updated: 2/10/2020 Revision: 0 Ref:

close

References

  1. Active Server Pages,  , http://msdn.microsoft.com/en-us/library/aa286483.aspx
  2. ASP Overview,  , http://msdn.microsoft.com/en-us/library/ms524929%28v=vs.90%29.aspx
  3. ASP Best Practices,  , http://technet.microsoft.com/en-us/library/cc939157.aspx
  4. ASP Built-in Objects,  , http://msdn.microsoft.com/en-us/library/ie/ms524716(v=vs.90).aspx
  5. Response Object,  , http://msdn.microsoft.com/en-us/library/ms525405(v=vs.90).aspx
  6. Request Object,  , http://msdn.microsoft.com/en-us/library/ms524948(v=vs.90).aspx
  7. Server Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525541(v=vs.90).aspx
  8. Application Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525360(v=vs.90).aspx
  9. Session Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms524319(8v=vs.90).aspx
  10. ASPError Object,  , http://msdn.microsoft.com/en-us/library/ms524942(v=vs.90).aspx
  11. ObjectContext Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525667(v=vs.90).aspx
  12. Debugging Global.asa Files,  , http://msdn.microsoft.com/en-us/library/aa291249(v=vs.71).aspx
  13. How to: Debug Global.asa files,  , http://msdn.microsoft.com/en-us/library/ms241868(v=vs.80).aspx
  14. Calling COM Components from ASP Pages,  , http://msdn.microsoft.com/en-us/library/ms524620(v=VS.90).aspx
  15. IIS ASP Scripting Reference,  , http://msdn.microsoft.com/en-us/library/ms524664(v=vs.90).aspx
  16. ASP Keywords,  , http://msdn.microsoft.com/en-us/library/ms524672(v=vs.90).aspx
  17. Creating Simple ASP Pages,  , http://msdn.microsoft.com/en-us/library/ms524741(v=vs.90).aspx
  18. Including Files in ASP Applications,  , http://msdn.microsoft.com/en-us/library/ms524876(v=vs.90).aspx
  19. ASP Overview,  , http://msdn.microsoft.com/en-us/library/ms524929(v=vs.90).aspx
  20. FileSystemObject Object,  , http://msdn.microsoft.com/en-us/library/z9ty6h50(v=vs.84).aspx
  21. http://msdn.microsoft.com/en-us/library/windows/desktop/ms675944(v=vs.85).aspx,  , ADO Object Model
  22. ADO Fundamentals,  , http://msdn.microsoft.com/en-us/library/windows/desktop/ms680928(v=vs.85).aspx
close
IMAGE

Home 5

Business

Management

HBR 3

Information

Recreation

Hobbies 8

Culture

Chinese 1097

English 337

Reference 67

Computer

Hardware 151

Software

Application 198

Digitization 25

Latex 9

Manim 121

Numeric 19

Programming

Web 283

Unicode 494

HTML 65

CSS 58

ASP.NET 174

OS 389

DeskTop 7

Python 19

Knowledge

Mathematics

Formulas 8

Algebra 25

Number Theory 206

Trigonometry 18

Geometry 21

Calculus 67

Complex Analysis 21

Engineering

Tables 8

Mechanical

Mechanics 1

Rigid Bodies

Statics 92

Dynamics 37

Fluid 5

Fluid Kinematics 5

Control

Process Control 1

Acoustics 19

FiniteElement 2

Physics

Electric 27

Biology 1

Geography 1


Copyright © 2000-2020 Sideway . All rights reserved Disclaimers last modified on 06 September 2019