By Ian Griffiths, Matthew Adams
Price: $44.95 USD
£31.95 GBP
Cover | Table of Contents | Colophon
void or Nothing); overloading
based on return type alone is not allowed. (C++
doesn't allow this either.) Note that methods that
return void or Nothing in VB
are declared using the Sub statement rather than
the Function statement.System.Xml namespace, GUI services are provided by
the
System.Windows.Forms
namespace, and graphical services are provided by the
System.Drawing namespace. Namespaces are
hierarchical, and large namespaces are frequently subdivided into
several smaller namespaces, e.g., the design-time parts of the
Windows Forms API appear in the
System.Windows.Forms.Design namespace.System.Drawing
namespace, although we will discuss other relevant classes as
necessary.Control class, the foundation of all UI
applications and the subject of the next chapter. In fact, almost
everything that happens in a .NET UI application revolves around
controls, so most of the rest of the book is about controls.System.Windows.Forms namespace defines a class
called Control. This class is at the heart of all
Windows Forms applications. Any visual element of an
application—whether it is a window, a button, a toolbar, or a
custom user-defined control—is represented by an object of some
class deriving from Control.Control class within the Windows Forms framework,
and examines the basic behavior that all controls inherit from
Control. It also introduces the classes that
represent the traditional Windows controls.Control. For example, top-level windows are
represented by the Form class; each of the
standard Windows control types has a corresponding class (such as
Button and TreeView); you can
also define custom controls by creating your own classes. All these
inherit (either directly or indirectly) from the
Control class.Control,
they share a single implementation of the features common to all
controls. This ensures a certain minimum level of functionality and
guarantees consistent behavior across all control types. The
Control class defines standard properties, events,
and methods for all the common features of user interface components.
These include size and position, input handling, and appearance.Control class also defines the nature of the
relationships controls on a form have with one another. As with
classic Windows programming, a parent-child relationship is
supported—a control may contain several child controls, and
most controls (except top-level windows) have a parent control. The
containment relationship is detailed in the next chapter, but it
affects all controls for certain operations, such as moving and
resizing windows. It also has some slightly more subtle implications
for features such as focus management and control validation.Control. For example, top-level windows are
represented by the Form class; each of the
standard Windows control types has a corresponding class (such as
Button and TreeView); you can
also define custom controls by creating your own classes. All these
inherit (either directly or indirectly) from the
Control class.Control,
they share a single implementation of the features common to all
controls. This ensures a certain minimum level of functionality and
guarantees consistent behavior across all control types. The
Control class defines standard properties, events,
and methods for all the common features of user interface components.
These include size and position, input handling, and appearance.Control class also defines the nature of the
relationships controls on a form have with one another. As with
classic Windows programming, a parent-child relationship is
supported—a control may contain several child controls, and
most controls (except top-level windows) have a parent control. The
containment relationship is detailed in the next chapter, but it
affects all controls for certain operations, such as moving and
resizing windows. It also has some slightly more subtle implications
for features such as focus management and control validation.Control class sits at the
root of this hierarchy, but there are specializations for various
types of controls, as Figure 2-1 shows. All
the built-in controls (buttons, labels, tree views, etc.) inherit
directly from the Control class. As you will see
in Chapter 5, you can write your own controls that
do the same.
Control class
provides uniform management of all the standard facets of a control,
including visual features such as color, caption, and typeface,
dynamic features such as event handling and accessibility, and other
standard behaviors such as layout management. There are two ways of
using most of these features: at design time in the Windows Forms
designer and at runtime from code.private System.Windows.Forms.Button button1;
...
private void InitializeComponent()
{
...
this.button1 = new System.Windows.Forms.Button();
...
this.button1.Location = new System.Drawing.Point(8, 8);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "button1";
...
}
Private WithEvents Button1 As System.Windows.Forms.Button Private Sub InitializeComponent() Me.Button1 = New System.Windows.Forms.Button() Me.SuspendLayout() ' 'Button1 ' Me.Button1.Location = New System.Drawing.Point(8, 8) Me.Button1.Name = "Button1" Me.Button1.TabIndex = 0 Me.Button1.Text = "Button1" ... End Sub
Button, have several different modes, each
of which is represented by a different class in Windows Forms. In
this case, a Win32 window style is also specified to indicate which
particular flavor of this class the relevant .NET type represents.)|
Control class
|
Equivalent Win32 window class (and style)
|
Purpose
|
|---|---|---|
|
Buttons
| ||
Button |
Button (BS_PUSHBUTTON) |
Normal button for actions (e.g., OK or Cancel)
|
CheckBox |
Button (BS_CHECKBOX) |
Yes/no selection button
|
Control class is central to any Windows Forms
application. Every visible element of the user interface is a control
of some kind. This means there is a rich standard set of features
that all controls support. All the standard Windows controls have
counterparts in Windows Forms.Form class. As with
any user interface element, the Form class
inherits from the Control class, but it adds
windowing features, such as management of the window border and
interaction with the Windows taskbar. All Windows Forms applications
have at least one class derived from Form.Main
. It doesn't matter
which class this is defined in, although Visual Studio always makes it a member of
the main form that it puts in any new project. It generates code like
the C# code shown in Example 3-1.[STAThread]
static void Main()
{
Application.Run(new Form1());
}
Main visible if
you're developing with C#, it hides it if
you're developing with Visual Basic. In Visual Basic
projects, the code for Main is not displayed in
the form's code window, nor is it listed in Class
View or in the Object Browser. However, examining a compiled Windows
Forms application using ILDASM, the .NET disassembler, indicates that
a hidden public method named Main is present in
the application's main form, as Figure 3-1 shows. Its source code corresponds to
that shown in Example 3-2.Form class. Of course, Form
derives from Control, as do all classes that
represent visual elements, so we have already seen much of what it
can do in the previous chapter. But we will now look at the features
that the Form class adds.Form class
directly—any forms you define in your application will be
represented by a class that inherits from Form.
Adding a new form in Visual Studio .NET simply adds an appropriate
class definition to your project. We will examine how it structures
these classes when generating new forms, and we will look at how it
cleans up any resource used by the form when it is destroyed. Then,
we will consider the different types of forms. Finally, we will look
at extender properties. These provide a powerful way of extending the
behavior of all controls on a form to augment the basic
Control functionality.private
fields in C# and Friend fields in VB to hold the
contents of the form. (The Designer inserts new fields here as you
add controls to the form.) Next is the constructor, followed by the
Dispose and InitializeComponent
methods; these are all described below. If this is the main form in
your application, the program's entry point (the
Main method described above) will follow in C#
programs; in VB programs, it will be added by the compiler at compile
time, but will not be displayed with the form's
source code. Finally, any event handlers for controls on your form
will be added at the end of the class.Control class and the
ContainerControl class, paying particular
attention to the implications of containment for focus and validation
events.Parent
property (of type
Control). If you examine this property on a
control on a form, you will typically find that it refers to that
form. However, many controls can behave as both a parent and a
child—if you place a button inside a group box on a form, the
button's parent will be the group box, and the group
box's parent will be the form.ScrollableControl
class. This is the base class of ContainerControl
and of Panel, which means that this behavior is
available to all forms, panels, and user controls.AutoScroll property to
true. If the window is smaller than its contents,
scrollbars will be added automatically. Of course, the class will
need some way of knowing how large the window's
contents are. By default, it will deduce this from its child
controls—it will assume that the window's size
should be exactly large enough to hold all the controls.AutoScrollMargin
property. This property's type is
Size, which enables you to specify the vertical
padding and the horizontal padding separately. So specifying a margin
of ResourceManager class,
which is defined in the System.Resources
namespace.ResourceManager class allows named pieces of
data to be retrieved. (We'll see where this data is
stored in just a moment.) For example, rather than hardcoding an
error message directly into the source, we can do the following in
C#:ResourceManager resources = new ResourceManager(typeof(MyForm));
string errorWindowTitle = resources.GetString("errorTitle");
string errorText = resources.GetString("errorFileNotFound");
MessageBox.Show(errorText, errorWindowTitle);
Control class provides a very rich set of
features, inevitably it cannot be all things to all people. UI
innovations continue to emerge, so even if the
Control class were to represent the state of the
art today, in time, it would inevitably end up looking short on
features.Control class. It is
possible to place a component on a form that adds a feature to every
single control on that form. Such a component is referred to as an
extender provider. We will see how to write
extender providers in Chapter 9, but no discussion
of forms would be complete without looking at how to use them.ToolTip class. As
mentioned in Chapter 2, the
Control class does not provide ToolTip support.
But this doesn't matter—the framework has a
ToolTip class that is able to augment any control
with ToolTip support. If you drop the ToolTip
component onto a form, it will appear in the component tray at the
bottom of the designer. (All non-UI components appear here; the only
kind of component that has any business appearing on the form at
design time is a control, so everything else appears in the component
tray. And the ToolTip isn't
strictly a UI component; it is a component that modifies the behavior
of other controls.) Once you have done this, if you look at the
Properties tab for any of the controls on your form, you will see
that each has acquired a ToolTip property in the
Misc category. If you set some text for this property for a
particular control, that text will appear as a ToolTip whenever the
mouse hovers over that control at runtime.Form class. These classes are typically generated
by the Visual Studio .NET forms designer, which uses a standard
structure for handling initialization and shutdown. An application
could have just one form or it might have several, but in any case,
its lifetime is managed by the Application class.
The controls in a form can have their layout managed automatically,
and while there are several built-in styles of automatic layout, the
underlying mechanisms are also exposed, allowing custom automatic
layout systems to be written. Another useful feature of forms is the
ability to use an extender provider—these are components which
add pseudo properties (so-called extender
properties) to some or all the controls on a form,
allowing the basic functionality of the Control
class to be augmented.Menu class, which is arguably misnamed, because it
represents a more abstract concept than its title suggests. It can
correspond to any element of a menu structure, and it is the base
class of all the other types in the menu object model. So while a
Menu object might represent a menu, it could just
represent a single item of a menu. (Perhaps
MenuElement would have been a more descriptive
name.) Representing menus and menu items with the same base type
seems a little strange at first, but it makes sense when you consider
that menus can be hierarchical. A menu item might well be a nested
menu, in which case, it makes sense for that menu item to be
represented by an object whose class derives from
Menu.Menu class is to represent the
structure of a menu. You can find out whether a particular
ToolBar class, and individual buttons on it are
represented by the ToolBarButton class. Note that
these classes provide a fairly basic style of toolbar—Windows
Forms provides no support for undocking toolbars or even rearranging
them.ToolBar
is a fairly simple class. It inherits
from Control and must be docked; most applications
dock the toolbar to the top of the window. ToolBar
is a simple class to use—it adds only a few properties to its
base class.Appearance
property, which must be one of
the members of the ToolBarAppearance enumeration:
either Normal (the default) or
Flat. When set to Normal, each
toolbar button has a button-like raised edge. However, most
applications favor the Flat style these days,
where the toolbar appears completely flat, and the buttons have no
outline except when the mouse is over them.ToolBar also controls where any text
associated with a button appears through its
TextAlign
property. (A toolbar button may
optionally have a text label, like the Back button on Internet
Explorer.) This property's type is the
ToolBarTextAlign enumeration, and it can be either
Right or Underneath. The
default is Underneath.Buttons
, whose type is
ToolBarButtonCollection. This contains all the
ToolBarButton objects on the toolbar. This is used
in a similar way to the other collections we have seen, such as the
System.Collections.Hashtable—it is designed
to store associations between objects. We can use this to remember
which toolbar buttons are equivalent to which menu items. Although
the Designer cannot store these associations in a
hash table for you automatically, it
only requires a small amount of code in your form's
constructor. The following is the necessary C# code:// Hashtable to associate buttons with menu items
private Hashtable toolbarButtonToMenu;
public MyForm()
{
InitializeComponent();
// Create hash table
toolbarButtonToMenu = new Hashtable();
// Associate ToolBarButtons with MenuItems
toolbarButtonToMenu(toolBarFileNew) = menuFileNew;
toolbarButtonToMenu(toolBarFileOpen) = menuFileOpen;
toolbarButtonToMenu(toolBarEditCopy) = menuEditCopy;
toolbarButtonToMenu(toolBarEditCut) = menuEditCut;
toolbarButtonToMenu(toolBarEditPaste) = menuEditPaste;
toolbarButtonToMenu(toolBarEditDelete) = menuEditDelete;
}
' Hashtable to associate buttons with menu items
Private toolbarButtonToMenu As HashTable
Public Sub New()
InitializeComponent()
' Create hash table
toolbarButtonToMenu = New Hashtable()
' Associate ToolBarButtons with MenuItems
toolbarButtonToMenu(toolBarFileNew) = menuFileNew
toolbarButtonToMenu(toolBarFileOpen) = menuFileOpen
toolbarButtonToMenu(toolBarEditCopy) = menuEditCopy
toolbarButtonToMenu(toolBarEditCut) = menuEditCut
toolbarButtonToMenu(toolBarEditPaste) = menuEditPaste
toolbarButtonToMenu(toolBarEditDelete) = menuEditDelete
End Sub