The Windows Forms Application Model

The application programming model for Windows Forms is primarily comprised of forms, controls, and their events.  The following facets of the Windows Forms application model are covered in this topic:

Forms

In Windows Forms, the Form class is a representation of any window displayed in your application. You can use the BorderStyle property of the Form class to create standard, tool, borderless, and floating windows. You can also use the Form class to create modal windows, such as dialog boxes. A special kind of form, the MDI form, can be created by setting the MDIContainer property of the Form class. An MDI form can contain other forms, called MDI child forms, within its client area. The Form class provides built in support for keyboard handling (tab order) and scrolling of the contents of the form.

When designing the user interface for your application, you typically create a class that derives from Form. You can then add controls, set properties, create event handlers, and add programming logic to your form.

Controls

Each component that is added to a form, such as a Button, a TextBox, or a RadioButton, is called a control. Windows Forms includes all of the controls commonly associated with Windows, as well as custom controls like the Windows Forms DataGrid.

You typically interact with controls by setting properties to alter their appearance and behavior. For example,  the following derived class of Form adds a Button control to the form, and sets its Size and Location.


Public Class HelloWorldForm
    Inherits Form

    Private components As Container
    Private WithEvents button1 as Button
    Private textBox1 As New TextBox

    <STAThread()> Shared Sub Main()
        System.Windows.Forms.Application.Run(New HelloWorldForm())
    End Sub

    Public Sub New()
        MyBase.New

        Me.Text = "Hello Windows Forms World"
        Me.AutoScaleBaseSize = new Size(5, 13)
        Me.ClientSize = new Size(392, 117)

        Me.MinimumSize = new Size(392, (117 + SystemInformation.CaptionHeight))

        button1 = new Button()
        button1.Location = new Point(56, 64)
        button1.Size = new Size(90, 40)
        button1.TabIndex = 2
        button1.Text = "Click Me!"

        textBox1.Text = "Hello Windows Forms World"
        textBox1.TabIndex = 1
        textBox1.Size = new Size(360, 20)
        textBox1.Location = new Point(16, 24)

        Me.AcceptButton=button1

        Me.Controls.Add(button1)
        Me.Controls.Add(textBox1)
    End Sub
End Class
VB

Control State is Modeless

Forms provide limited restrictions on when you can set properties for controls. Controls do not have modes that prevent their state from being updated. As soon as you have created a new instance of a control, you can alter its state. For example, the following code provides two examples that demonstrate valid ways of creating a Button control.


Dim button1 As New Button
button1.Location = New Point(256, 64)
button1.Size = New Size(120, 40)
button1.TabIndex = 1
button1.Text = "Click Me!"
Me.Controls.Add(button1)
VB



Dim button1 As New Button
Me.Controls.Add(button1)
button1.Location = New Point(256, 64)
button1.Size = New Size(120, 40)
button1.TabIndex = 1
button1.Text = "Click Me!"
VB

Windows Forms ensures that the code you create is valid. For example,  if you set a property that sets a Windows style bit for a Windows control, which can be set only when the control is created, the Windows Forms control discards the underlying Windows control and creates a new control for you. The only time that this capability is potentially undesirable is if you bypass Windows Forms and directly access the underlying HWND for the control. You cannot keep a reference to the HWND because it may be made invalid by a property set in your code.

Events

The Windows Forms programming model is event based. When a control changes state, such as when the user clicks a button, it raises an event. In order to handle an event, your application registers an event-handling method for that event. In Visual Basic there are two ways to register an event handling method:

  • If you declare the control variable using the WithEvents keyword, you can use the Handles keyword on the declaration of a method to register it as the event-handling method.


  • You can use AddHandler to register event handling methods at runtime.


The following code illustrates all two ways to register an event-handling method.


....
'Declare the button using WithEvents so that the compiler registers the event handler
Private WithEvents button1 As Button
....

'The event handling method for button1 - registered using Handles
Private Sub OnButton1Click(sender As Object, ByVal evArgs As EventArgs) Handles button1.Click
    MessageBox.Show("Text is: '" + textBox1.Text + "'")
End Sub

'The event handling method for the new button -  registered using AddHandler
Private Sub clickNewbutton(sender As Object, evArgs As EventArgs)
    MessageBox.Show("Hello from the new Button")
End Sub
....

VB

An event-handling method is called only for a specific event for a specific control. This allows you to avoid having a single method in your form that handles all events for all controls. This feature also makes your code easier to understand and maintain. Furthermore, because the Windows Forms event architecture is based on delegates, your event-handling methods are type safe and can be declared as private. This capability allows your compiler to detect method signature mismatches at compile time. It also keeps the public interface of your Form class uncluttered with public event-handling methods. You can find more information about delegates in the .NET Framework SDK documentation.

In Visual Basic you use RemoveHandler to unregister your event-handling method.

Event Classes

Each event has two supporting classes:

  • The EventHandler delegate class that is used to register your event-handling method. The signature of the EventHandler dictates the signature of your event-handling method.


  • The EventArgs class that contains data about the raised event.

The signature for an EventHandler is that the first argument contains a reference to the object that raised the event (the sender) and that  the second argument contains data about the event (an instance of an EventArgs). For example,  the Click event on a Button uses the the following event handler.


Public Delegate Sub EventHandler(sender As object, e As EventArgs)
VB


As a result, any event-handling method for the Click event must have the following signature.


<access> Sub <name>(sender As object, e As EventArgs)
VB

For strongly typed languages, a compile time error will occur if the event-handling method's signature does not match the delegate signature.

Many events use the generic EventHandler and EventArgs classes. However, some events require additional information that is specific to the type of raised event. For example, the mouse movement events include information about the position of the mouse pointer or mouse buttons. These events define their own classes that must inherit from the EventHandler and EventArgs classes. For example,  the MouseDown event uses the MouseEventHandler and MouseEventArgs classes.

Event Naming Conventions

An event can be raised both before and after specific kinds of state changes. The event that is raised prior to a state change is typically suffixed with "ing". The event that is raised after a state change is typically suffixed with "ed". For example, the SessionEnding event is raised prior to a state change, and the SessionEnded event is raised after a state change. If a state change causes only a single event to be raised, then that event typically does not have a suffix. For example, the Click event.

Cancelable Events

Depending on the situation in your application, you may want to cancel an event. Certain events can be cancelled. These events use the CancelEventHandler and CancelEventArgs classes. The CancelEventArgs class contains a property called Cancel. If this property is set to true, when the event-handling method returns, the event is cancelled. Typically, only events that are raised prior to a state change are cancellable. Canceling the event cancels the state change.

Handling Multiple Events with a Single Event Handling Method

If you wish to handle multiple events with a single event handler, you can do this by registering the same method with multiple events. Each event must have the same signature. When you use a single event-handling method for multiple events, you can determine which control raised  an event from the sender parameter. The following example illustrates a single event-handling method that handles events from two button controls.


....
Dim button1 As New Button
Dim button2 As New Button
....
AddHandler button1.Click, AddressOf button_Click
AddHandler button2.Click, AddressOf button_Click
....

'The event handling method
Private Sub button_Click(sender As Object, evArgs As EventArgs)
    If (sender = button1) Then
        MessageBox.Show("Button1 Pushed!")
    Else If (sender = button2) Then
        MessageBox.Show("Button2 Pushed!")
    End If
End Sub
VB

Creating Your Own Events

The Creating Controls section of the Windows Forms Quickstart describes how to define your own events.


Deterministic Lifetime and Dispose

The .NET Framework class model provides the Dispose method in the Component class. The Dispose method is called when a  component is no longer required. For example, Windows Forms calls the Dispose method on a form, and all of the controls contained within that form, when the form is closed. You typically use Dispose to free large resources in a timely manner and to remove references to other objects so that they can be reclaimed by garbage collection. It is also called to stop any executing program logic associated with the form. You should keep the code in your Dispose method as simple and robust as possible. If the Dispose method fails, large resources may not be released from memory.

Putting It All Together - A Simple Windows Forms Application

The following sample demonstrates the concepts mentioned previously. It shows how to:

  • Create and display a form as the main entry point of an application
  • Add controls to the form
  • Set properties on the controls
  • Register event-handling methods with controls
  • Get property values from a control
  • Display text in a message box
  • Add code to the Dispose method that is executed when the form is closed
 
VB Hello World

[Run Sample] | [View Source]


Copyright 2001 Microsoft Corporation. All rights reserved.