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.