module title - .net at jkudotnet.jku.at/buch/cd-de/dotnetdays/webfiles/dnrk... · web viewthe...

92
Windows Forms

Upload: trinhminh

Post on 30-Jun-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Windows Forms

2 Windows Forms

Overview

ObjectivesThis module describes the.NET Windows Forms namespace, the new plattform for Windows-based applications.

What You Will Learn Overview of important Windows Forms Classes Writing Windows-based .NET Applications

Related Topics Covered in This Lesson ADO.NET Common library module

Recommended Reading MSDN Online

Windows Forms 3

Section 1: Introduction

Introduction

There are many GUI librarys for the Windows operation system. But only Microsoft offers three more comfortable librarys - beside the core Windows API: Microsoft Foundation Classes, the Visual Basic object library and – with some restrictions – the Active Template Library. None of these libraries is usable by each programming language.

The Windows Forms library changes/reforms that. This library is usable by each .NET language: VB.NET, C#, Managed C++, JScript and any Thirdparty language.

4 Windows Forms

Section 1: Introduction

Basic concepts

The essential core component of the Windows Operating System is a window. A Window is a presentation and user interaction object which is configured via attributes and controlled by messages. Sending messages is a theoretical object oriented programming concept that is replaced by methods and properties in practice. Windows offers a set of predefined window classes. Because Windows is independent of any progamming language, these classes are not comparable with C++ classes (or similar object concepts). Windows classes are a combination of a structure and functions (especially the SendMessage function), but these are more loosely connected as in OOP classes. A first approach to improve this is the Microsoft Foundation Classes, a feature rich C++ library. But in fact, MFCs are only a thin layer over the Windows API.

.NET offers a new library, which is closely connected with the CLR and the .NET core classes: Windows Forms. This library is more straight forward as other GUI frameworks. Furthermore, this library is language independent.

Windows Forms 5

Section 1: Introduction

From Window to Control to Form

In .NET a Window is represented by a Control. As is typical for the .NET Framework, Control is a .NET class. Now, you derive a new class from Control to define a new control type (a new window class). The characteristics of this control are defined via properties. You can control a Control via methods.

A Form – a top level window – is a class derived from Control. This is comparable to the Windows API: an application window is a window class with some special attributes, like caption, border and so on. A Form is nothing else than a Control, nothing else than a window.

6 Windows Forms

Section 1: Introduction

Delegates and Events

A window is controlled by messages. Each window class has a central function, which receives these messages and does the necessary work. This function is called window proc(edure). On the other hand, this window proc sends messages to other windows to inform these about its status.

Visual Basic introduces the event concept to provide notifications for forms and other containers about its status, required actions and so on. This concept originally applied to COM/ActiveX, and is generally accepted. .NET uses events in a lot of cases.

.NET Events are strongly linked to Delegates. A Delegate is the object oriented model of a function pointer and therefore the base of callback functions. Delegates are type safe and cannot corrupt the memory of another object. Programmatically a delegate will be made of two parts:

a prototype of the function the implementation of the function

An example for a delegate declaration is

public delegate void MyDelegate( int parameter);Events in the .NET Framework are based on the delegate model. An Event is an instance of a delegate function. There is a producer, who raises an event, and there is a consumer who receives the event. In the programm, the event is a class member which acts as the connection

Windows Forms 7

point between the producer and the consumer (sender and receiver). The consumer must implement the Event/Delegate function - in this case called event handler – and attach this implementation to the producer via the event member. The producer raises an event, by calling the event function through this connection point.

The advantages of events in comparison to simple delegates are

a connection point is built by a list, therefore you can attach more than one event handler.

the mechanism to attach a handler is much simpler.

An example for an event declaration is

public event MyDelegate MyEvent;

The .NET Frameworks guidelines indicate that the delegate type used for an event should use two parameters, an object source parameter indicating the source of the event and an e parameter that encapsulates any additional information about the event. The type of the e parameter should be derived from the EventArgs class. For events that do not use any additional information, the .NET framework has already defined an appropriate delegate type: EventHandler.

Virtual functions for derived classesThe Windows Forms classes offer a second way to handle events for derived classes. An overridable method exists corresponding to each event. Instead of adding an event handler you can override this function. For example, a user control can override the OnPaint method to draw the output into the control client’s area.

8 Windows Forms

Section 1: Introduction

The Control Class

This class implements basic functionality and is the base class for many of the predefined controls (TextBox, TreeView, …) and for user controls. It handles user input via the keyboard and pointing device, message routing and security. Additionally it defines the bounds of a control (position and size), background color, border style, OLE drag and drop, and much more. It provides access to the window handle (hWnd) of the underlying window.

Besides the listed properties known from Visual Basic 6, there are some new functions:

Docking and Anchoring Special (MFC like) input handling Handling of child controls Client/Screen coordinates transformation Functions to locate other (related) controls

The control class does not implement painting – this must be done in a derived class/control. This means, the control is not visible. Because this is a basic class, it only has fundamental functionality. But the great base functionality make it simple to write custom contrlols.

Windows Forms 9

Section 1: Introduction

Forms

TextA Form is a representation of any window displayed in your application. The Form class can be used to create standard, tool, borderless, and floating windows. You can also use the Form class to create modal dialog boxes. A special kind of form, the MDI form, can contain other forms called MDI child forms.

For forms, the Text property specifie the caption of the window in the title bar. This is one of the major changes in comparison to classic VB, which uses the Caption property to set/get the window text. While Caption is often a default property, you must use Text explicitly.

You can use a form as the starting class in your application by placing a method called Main in the class. Adds code to create and show the form to the Main function. When the starting form is closed, the application is also closed.

There are some properties and functions, which are supported by forms, not by controls. Examples are:

MinimizeBox and MaximizeBox properties: Allow you to control whether the form should be minimized, maximized, or resized at run time.

AcceptButton, CancelButton properties: Declare which buttons react as OK- or Cancel-Button.

DesktopLocation: Gets or sets the location of the form on the Windows desktop.

Load event: Is raised once after the form is created. Activated event: Occurs when the form is activated in

code or by the user. ShowDialog: Displays a form as dialog

10 Windows Forms

Windows Forms 11

Section 1: Introduction

Inheritance

Depending on the Development Environment there are different ways to define new window types. If you work with the API functions, you fill a WNDCLASS structure, register it with RegisterClass and call CreateWindow to build a new window class. You can create many instances of a class with CreateWindow.

In Visual Basic 6 you create a new form class, set its properties and use the New statement to create an instance of this form. But you can only create new forms this way. To create a new control type you must create a UserControl, which really is an ActiveX Control.

The MFC offers a special solution. You must use CreateWindow – which is encapsulated through the Create method of the CWnd class – but the MFC framework defines the windows class description by self.

In .NET you can create your own controls and forms. The mechanism is always the same: derive a class from System.Windows.Forms.Control or System.Windows.Forms.Form. To define the attributes, you set properties or call methods. To handle events, you can attach event handlers or override the corresponding methods.

12 Windows Forms

Section 1: Introduction

Creating and using instances

Creating a form instance is very simple and very familiar for Visual Basic programmers:

VB.NET:

Dim frm as Form = new Form()frm.Text = “Caption”frm.Show()

C#:

Form frm = new Form();frm.Text = “Caption”;frm.Show();

You can use Forms as dialogs:

VB.NET:

Dim frm as Form = new Form()frm.Text = “Caption”frm.FormBorderStyle = FormBorderStyle.FixedDialogfrm.MinimizeBox = falsefrm.MaximizeBox = false

Windows Forms 13

frm.ShowDialog()

C#:

Form frm = new Form();frm.Text = “Caption”;frm.FormBorderStyle = FormBorderStyle.FixedDialog;frm.MinimizeBox = false;frm.MaximizeBox = false;frm.ShowDialog();Creating controls at the core is the same process. First you create an instance, then you add the instance to the Controls collection of the container (another control or a form). Appending the control to the Controls collection is essential, otherwise the control is invisible and not useable.

VB.NET

Dim txt as TextBox = new TextBox()frm.Controls.Add(txt)

C#

TextBox txt = new TextBox();frm.Controls.Add(txt);

14 Windows Forms

Section 1: Introduction

The System.Drawing namespace

Because position and size values often appear as Point or Rectangle values, Colors are based on GDI values and a window always is painted via GDI functions, there are relations to the System.Drawing namespace. This namespace encapsulates GDI+ and offers drawing functions, pens and brushes support and so on.

The Graphics class offers methods for drawing. This class is the .NET equivalent for a Windows API Device Context. You get a Graphics object by:

The paint event (which is linked to the WM_PAINT message)

Via CreateGraphics from the Control class Via FromHdc, which requires a Device Context By FromHwnd, which requires a window handle

(window handles are supported by the Control class)

Important System.Drawing members for the Windows Forms are:

Point: Represents an ordered pair of x and y coordinates that define a point in a two-dimensional plane.

Rectangle: Stores the location and size of a rectangular region.

Size: Represents the size of a rectangular region with an ordered pair of width and height.

Color: Represents an ARGB color.

Windows Forms 15

Section 2: Forms

Overview

Within a Windows-based application, the form is the primary element for user interaction. By combining controls and your own actions, you can request information from the user and respond to it. Besides single form applications there are Multiple Document Interface applications, which contains more than one form, if necessary with different document types. Additionally there are dialogs, a special type of forms.

16 Windows Forms

Section 2: Forms

GUI based applications

If you want to write Windows Forms applications, you must include SYSTEM.WINDOWS.FORMS.DLL in your project. In Visual Studio.NET you simply set a reference to these DLLs. If you works with the command line compilers, you use a /reference (or /r) parameter.

The starting point of a Forms application is the Main function. But in contrast to console applications you use the System.Windows.Forms.Application object to open the main window and enter the message loop. The Application class offers the static Run method, which get a reference to the main form as parameter. After calling Run, your application is ready to receive events, is ready to interact with the user.

namespace WF1{ using System; using System.Windows.Forms;

class App { public static void Main() { Form frm = new Form(); frm.Text = "Windows Forms "; Application.Run( frm );

Windows Forms 17

} }//class}//namespace

In the simplest case, you use the Form class directly. The sample App1 creates a Form instance, sets the window text (caption) and calles Run with this instance as parameter. The result is a typical application window with a specific caption but nothing else. There is no output, no menu, nothing.

For a more realistic application you derive a class from Form and override some functions. You can override OnPaint to display application data, or you can override OnMouseDown to handle mouse clicks.

class MyForm: Form{ public MyForm() { this.Text = "Windows Forms "; } protected override void OnPaint ( PaintEventArgs e) {//..}}Application.Run shows only the main form of an application. Additional forms are opened with the Show method of the Form class.

18 Windows Forms

Section 2: Forms

Forms

One of the newest features for VB programmers is the dimension handling. A VB form offers properties like Width and Height for the outer dimensions and ScaleWidth and ScaleHeight for the inner dimensions (client area) of a form. NET makes these values available as Size and Rectangle structures. Instead of Width and Height you use the Size property (which returns a Size structure), instead of ScaleWidth and ScaleHeight you use ClientSite. The Size structure has a Width and a Height property, so you have access to these values.

You can assign an icon to a form. The Icon property expects an Icon object as value. Icon is a class from System.Drawing and offers methods to load icons from files.

The Load event is continuously supported. But instead of the Unload event now you must handle the Closing event to prevent the form from closing. You can do some final work by handle the Closed event, which is raised after the form has closed.

Keep in mind, the Form class inherits a lot of events from Control – look at the Members section in the documentation to display all methods, properties and events.

Some of the new elements are:

DesktopLocation: Gets or sets the location of the form on the Windows desktop.

DesktopBounds: Gets or sets the size and location of the form on the Windows desktop.

Windows Forms 19

StartPosition: Gets or sets the starting position of the form at run time.

TopMost: Gets or sets a value indicating whether the form should be displayed as the top-most form of your application.

TopLevel: Gets or sets a value indicating whether to display the form as a top-level window.

Forms and contained ControlsForms often use child controls for user input and data view. Adding a control to a form is a five step process:

1. create the control instance

2. set the attributes of the control (Text, BackColor,…)

3. set the location and dimensions of the control

4. add event handlers for the control

5. add the control to the controls collection of the form

After that, the controls are visible and usable as child windows of the form (excepted if they are invisible or disabled). You can go through all these steps by hand, and this is a good way to become an Windows Forms expert. But in practice, you will often use the Visual Studio Designer or the SDKs Forms Designer. Both tools generate source code.

This is the code to add a button to a form:

Step 0: declare the Button variable

private Button btn;Step 1: create the instance

btn = new Button();Step 2: set the attributes

btn.Text = "&Open Dialog...";Step 3: set location and dimensions

btn.Location = new Point(0,0);btn.Size = new Size(100, BUTTONHEIGHT);Step 4: add event handlers

btn.Click += new EventHandler( this.OpenDialog );Step 5: add the control to the controls collection

this.Controls.Add( btn );As long as the form is open, you can call methods and properties of the controls.

20 Windows Forms

Section 2: Forms

Dialogs

A dialog is nothing else than a window with special message handling. Particulary a modal dialog prevents keyboard and mouse input for all windows, excepted the dialog window. In .NET you use the ShowDialog method to open a form as dialog.

ShowDialog returns a DialogResult value, which represents the result. This property has the type DialogResult, which is an enumeration.

Member Name Description Abort The dialog box return value is Abort (usually

sent from a button labeled Abort).

Cancel The dialog box return value is Cancel (usually sent from a button labeled Cancel).

Ignore The dialog box return value is Ignore (usually sent from a button labeled Ignore).

No The dialog box return value is No (usually sent from a button labeled No).

None Nothing is returned from the dialog box. This means that the modal dialog continues running.

OK The dialog box return value is OK (usually sent from a button labeled OK).

Retry The dialog box return value is Retry (usually sent from a button labeled Retry).

Yes The dialog box return value is Yes (usually

Windows Forms 21

sent from a button labeled Yes).

These values can be assigned to the DialogResult property of the Button object or can be set in the event handlers of the buttons. An OK Button should return DialogResult.OK, a Cancel Button DialogResult.Cancel. The caller can evaluate this value. The example displays the InputText from the dialog only if the OK Button was used to close the dialog.

dlg = new MyDialog();if( dlg.ShowDialog() == DialogResult.OK ){ MessageBox.Show(dlg.InputText, "InputText" );}Often the OK Button should be linked to the Return Key, and the Cancel Button to the Esc Key. For that, the Form class offers the properties AcceptButton and CancelButton:

this.AcceptButton = cmdOK;this.CancelButton = cmdCancel;Unfortunately there is no “This form is a dialog property” property, so you must set some single properties for a typical presentation:

this.FormBorderStyle = FormBorderStyle.FixedDialog;this.MinimizeBox = false;this.MaximizeBox = false;You set the start position for a form via the StartPosition property. Dialogs are often centered on the screen:

this.StartPosition = FormStartPosition.CenterScreen;Return valuesBecause the DialogResult value only informs you which button has closed the form, you must read the values from the controls. If a control is public, you can use its properties directly. Additionally you can write some special properties which get back the values.

MessageBoxThere is one famous dialog box in the system: the MessageBox dialog for simple user informations and questions. This dialog is encapsulated in the MessageBox class and opened by its Show method.

22 Windows Forms

Windows Forms 23

Section 2: Forms

MDI applications

A Multiple Document Interface (MDI ) application is a combination of two forms: the Main Form and the Child Form. Because the child forms are tied to the client area of the main form, the main form is called Container Form too. Child forms are children of the container form.

To create an MDI application you need at least two Form classes: one for the Main Form and one for the Child Form. But an MDI application can have more than one Child Form. The Main Form must set the IsMdiContainer property to true. Additioanly you must set the MdiParent property of each Child Form instance. This must reference the Main Form instance.

The best place to set the IsMdiContainer property is the constructor:

public MainForm(){ this.IsMdiContainer = true; // more statements like.. this.Text = "MDI"; }Often the Child Forms are created in the event handler for a menu item:

protected void DoNew(object sender, EventArgs e){ ChildForm frm = new ChildForm();

24 Windows Forms

frm.MdiParent = this; frm.Show();}You can find out the number of Child Forms through the Length property of the MdiChildren array, which includes all child forms. Some other interesting properties and methods are:

IsMdiChild: Gets a value indicating whether the form is a multiple document interface (MDI) child form.

IsMdiContainer: Gets or sets a value indicating whether the form is a container for multiple document interface (MDI) child forms.

ActiveMdiChild: Gets the currently active multiple document interface (MDI) child window.

LayoutMdi: Arranges the Multiple Document Interface (MDI) child forms according to value.

Windows Forms 25

Section 3: Using Controls

Overview

Windows offers a set of very useful controls like ComboBox, TreeView or ListView. These controls are available in the .NET framework through classes. Because these classes are derived from the Control class, you can use them like all other controls.

Additionally there are some interesting layout features, which simplify the arrangement of controls in the client area of a form.

26 Windows Forms

Section 3: Using Controls

Layout

Often you wish to change the position and dimensions of controls at runtime. Today, you handle the resize event (WM_SIZE for API programmers), calculate the new position, width and height and call some methods like Move or SetWindowPos. The Windows Forms library offers two very helpful concepts to simplify these proceedings: Anchoring and Docking.

AnchoringWhen a control is anchored to a form (or another container) and the form is resized, the control maintains the distance between the control and the anchor positions (which is the initial postion). Anchoring is realized by the Anchor property. You can set this property to a (bitwise) combination of the AnchorStyle values.

A good example is a form with two buttons. Their Anchor properties are AnchorStyle.Left | AnchorStyle.Top and AnchorStyle.Right | AnchorStyle.Top. If you resize the form, the first button maintains its position at the left and top border, and the second button maintains its position at the right and top border. The first button is never moved, but the second button is always repositioned. The core characteristic feature of Anchoring is the fixed distance to the borders of the container.

DockingIf you use the Dock property, a control is coupled with two edges of the container. Then the control is horizontally or vertically resized when the container is resized. In practice you do not indicate the edges, you indicate a border. If

Windows Forms 27

you dock a control to the left border, it is connected with the top left and bottom left edge. The value of the Dock property is one of the DockStyle values.

A special case is DockStyle.Fill: This value docks the control to all edges. The control fills in the complete client area of the container.

SplitterThe Splitter control provides user resizing of docked elements at run time. To use a Splitter you can dock any control to an edge of a container and then dock the splitter to the same edge. The splitter will then resize the previous control in the docking order.

If you want to write a Windows Explorer like application with two controls (TreeView and ListView) set the Dock property of the left control to DockStyle.Left and the Dock property of the second control to DockStyle.Fill. The Splitter control must be docked left.

28 Windows Forms

Section 3: Using Controls

Buttons

In the Windows API buttons are defined by the window class BUTTON. This class realizes different types of Buttons: push buttons, check boxes, radio buttons and group boxes. With the owner draw attribute, a button can be painted by the parent window.

In the .NET framework, the BUTTON class is encapsulated by ButtonBase. This is an abstract base class. Only derived classes can be instantiated: Button, CheckBox, RadioButton. Unlike in the API a group box is not based on a button. The .NET GroupBox class is directly derived from the Control class.

ButtonBase offers very basic functionality only. There is an Image property to assign a picture, a DefaultSize property and so on. But there is nothing that looks like a button.

The Button class realizes a push button. Because all the basic functions are implemented in the Control class, there is only one interesting aspect: the DialogResult property. If you set this property to a value varying of DialogResult.None, then ShowDialog returns this value if the button is clicked.

Normally a CheckBox is checked or not, and you set or get this value by the Checked property. Additionally a CheckBox can have an indeterminate state. You must set the ThreeState property to true and use CheckState to verify the value. CheckState can be:

CheckState value Description

Windows Forms 29

Checked The check box displays a check mark.

Unchecked The check box is empty.

Indeterminate The check box displays a check mark and is shaded.

You get the value of a RadioButton by the Checked property too. But there is no ThreeState property.

Both, CheckBox and RadioButton offer the AutoCheck property. This gets or sets a value indicating whether the Checked or CheckState values and the check box's appearance are automatically changed when the check box is clicked.

30 Windows Forms

Section 3: Using Controls

Text Controls

Windows offers two text oriented controls: TextBox and RichTextBox. TextBox is based on the EDIT class and is one of the oldest existing Windows controls. RichTextBox encapsulates the RTF based Rich Edit Control (RICHEDIT_CLASS).

The .NET framework offers a base class for both types: TextBoxBase. This class declares core functions for different types of text classes. These functions contain clipboard operations, selection handling and so on. There is a special property for multiline text blocks, which converts the text in an array: Lines. Each element in this array holds one line. You can assign a new array to this property too.

The properties which manage selection handling are renamed: SelectionStart, SelectionLength and SelectedText. AcceptsTab gets or sets a value indicating whether pressing the TAB key in a multiline text box control types a TAB character in the control instead of moving the focus to the next control in the tab order. The Modified property indicates that the text box control has been modified by the user since the control was created or its contents were last set.

The AppendText method appends text to the current text of text box. Clear removes all text from the text box control. ClearUndo clears information about the most recent operation from the undo buffer of the text box. The Select method selects a range of text in the text box, SelectAll does that for the whole text.

TextBox and RichTextBox are derived from TextBoxBase.

Windows Forms 31

TextBoxTextBox offers some individual members.

AcceptsReturn: Gets or sets a value indicating whether pressing ENTER in a multiline TextBox control creates a new line of text in the control or activates the default button for the form.

CharacterCasing: Gets or sets whether the TextBox control modifies the case of characters as they are typed.

PasswordChar: Gets or sets the character used to mask characters of a password in a single-line TextBox control.

RichTextBoxThe RichTextBox control allows the user to enter and edit text while also providing more advanced formatting features than the standard TextBox control. Text can be assigned directly to the control or can be loaded from a Rich Text Format (RTF) or plain text file. The text within the control can be assigned character and paragraph formatting.

Specific properties are

AutoWordSelection: Gets or sets a value indicating whether automatic word selection is enabled.

DetectUrls: Gets or sets a value indicating whether or not the RichTextBox will automatically format a Uniform Resource Locator (URL) when it is typed into the control.

32 Windows Forms

Section 3: Using Controls

Simple List controls

The .NET framework contains some list controls, which are based on the abstract base class ListControl.

ListBoxThe ListBox control represents a standard Windows list box control. All items of a ListBox are stored in a ListBox.ObjectCollection. This collection offers properties and methods to add, locate and access items. You can iterate over an ObjectCollection (C#: foreach, VB: For Each) or get, set a single item through the Item property.

There are two other collections. ListBox.SelectedIndexCollection includes the indices of the selected items. You can use these values to access single items via the Item property of the ListBox.ObjectCollection. ListBox.SelectedObjectCollection refers to the selected items and you can directly use these items.

The Items, SelectedItems, and SelectedIndices properties provide access to the three collections that are used by the ListBox.

ListBox offers the overridable method CreateItemCollection to create a new instance of the collection. You can override this method and use an own implementation, custom made for your application. This is very interesting in combination with the Owner Draw mode of a ListBox.

The ListBox provides features that enable you to efficiently add items to the ListBox and to find text within the items of the list. The BeginUpdate and EndUpdate

Windows Forms 33

methods enable you to add a large number of items without the control being repainted each time an item is added to the list. The FindString and FindStringExact methods enable you to search for an item in the list that contains a specific search string.

ComboBoxComboBox is a combination of a ListBox and a TextBox. Consequently this class offers properties and functions from both types. Examples are the Items collection to access the stored values and the SelectedText property to access the selected text in the TextBox.

CheckedListBoxAlso derived from ListBox ist CheckedListBox. Each item of this list is combined with a checkbox. CheckedListBox offers properties and methods to work with these checkboxes.

Owner Draw ListsTypically a ListBox displays its values as text. But what about images, item specific colors and so on? The original Windows listbox class support an owner draw mode for such cases. The .NET ListBox class supports this functionality too. You can paint each item individually by following these steps:

Set the DrawMode property to DrawMode.OwnerDrawVariable or DrawMode OwnerDrawFixed. DrawFixed means, all items have the same height, while with DrawVariable any item can have an individual height. The default value of DrawMode ist DrawMode.Normal, so that the ListBox paints its content by its self.

Override the methods OnMeasureItem and OnDrawItem or handle the MeasureItem and DrawItem events. The first method will be called to determine the height of the items. OnDrawItem will be called to draw a single item. Both methods get a parameter with information about the items’ context.

34 Windows Forms

Section 3: Using Controls

Complex List controls

Additionally to ListBox & Co. there are some more complex controls: ListView and TreeView

ListViewA ListView can display data structures in four different views: list, small icons, large icons and details. Each item displays a caption and an image. In the details view each item appears on a separate line with further information about each item arranged in columns. The far left most column contains a small icon and label, subsequent columns contain sub items, for example the other fields of a data structure. A column has a header which can display a caption for the column.

The ListView class corresponds with the ListViewItem class to store the item values and some collections, similar to the ListBox class. These collections are

ListView.ListViewItemCollection ListView.SelectedIndexCollection ListView.SelectedListViewItemCollection ListView.CheckedIndexCollection ListView.CheckedListViewItemCollection ListView.ColumnHeaderCollectionTo enhance the functionality of a ListView, one aspect is very intersting: you can store more values than are visible columns. For Example: you have a list with four columns for file entries. These columns display the name of a file or directory as well as the size, the attributes and the creation date. Additionally to this visible columns, you can store a fifth value, which indicates the type of an item:

Windows Forms 35

directory or file. This value is not visible, but you can set and get it, just like the other four values.

TreeViewA TreeView displays a hierarchical list of items or nodes. Each node includes a caption and an optional image. If a node has sub-nodes, the user can collapse or expand the node. The caption is editable at runtime.

The values of a TreeView are stored in TreeNode objects. The matching collection is TreeNodeCollections. Similar to ListView there is the class TreeView.CheckedNodeCollection for checked nodes.

ImageListAn ImageList is a container for images. It is an invisible component that stores images for other controls. If a ListView displays icons in the first column, these icons are stored in an ImageList and referred by an index. The ImageList class offers a Draw method, but normally you do not use this function. The linked controls handle the drawing of the images. You add the required images to the list and set the index of the list items to the suitable image.

36 Windows Forms

Section 3: Using Controls

Menus

Menus are realized by a class hierachy. Menu is the abstract base class for the MainMenu, MenuItem, and ContextMenu classes.

MenuItemThe most important class for programmers is MenuItem. A MenuItem acts as a single menu item, but it can contains subitems. A subitem is represented by a MenuItem too. MenuItem has an overloaded set of constructors. The simple variant requires only a caption string. But in a lot of cases you will use the constructor with an event handler as second argument.

MenuItem mi = new MenuItem("&File");mi.MenuItems.Add( new MenuItem( "&New", new EventHandler( this.DoNew) ) );mi.MenuItems.Add( new MenuItem( "&Save", new EventHandler( this.DoSave) ) );You can assign an event handler after the creation by the OnClick event. Other constructors offer more arguments, like a shortcut or an array of subitems.

The Popup event enables you to perform tasks before a menu is displayed, such as disabling the Copy item if no test is selected. The Select event enables you to perform tasks such as providing detailed help for your application's menu items when the user places the mouse cursor over a menu item.

More details of an MenuItem are available through its properties.

Windows Forms 37

Checked: Gets or sets a value indicating whether a check mark appears next to the text of the menu item.

Enabled: Gets or sets a value indicating whether the menu item is enabled.

MenuID: Gets a value indicating the Windows identifier for this menu item.

Mnemonic: Gets a value indicating the mnemonic character that is associated with this menu item.

ShortCut: Gets or sets a value indicating the shortcut key associated with the menu item.

ShowShortcut: Gets or sets a value indicating whether the shortcut key that is associated with the menu item is displayed next to the menu item caption.

RadioCheck: Gets or sets a value indicating whether the MenuItem, if checked, displays a radio-button instead of a check mark.

MdiList: Gets or sets a value indicating whether the menu item will be populated with a list of the Multiple Document Interface (MDI) child windows that are displayed within the associated form.

MainMenuTo assign a menu to a form, you must create a MainMenu object. You can assign this object to the Menu property of a form:

this.Menu = new MainMenu(); // this refers to the form

ContextMenuThe ContextMenu class represents shortcut menus that can be displayed when the user clicks the right mouse button over a control or area of the form. Controls (and therefore forms) have a ContextMenu property that can bind such a menu. If you use this property, the Context Menu is automatically opened if the user clicks the right mouse key in the client area of an control. But you can display a Context Menu manually by the Show method.

More EventsIf the ContextMenu property is changed then a ContextMenuChanged event occurs. The MenuStart event is raised when any menu item in the menu is clicked by the user. You can use this event similar to the Popup event. The MenuComplete event signale that all menues are closed. For example, this is the right moment to reset a description text on the statusbar.

38 Windows Forms

Section 3: Using Controls

Toolbars

Toolbars are an alternative GUI element to menus. .NET realizes toolbars through the ToolBar class. A toolbar contains a set of buttons, which are represented by the ToolBarButton class in the .NET framework. To use a toolbar in a from

you create a ToolBar object add this object to the Controls collection of the form create some ToolBarButton objects configure these buttons (set the text and/or image and

so on) add these buttons to the Buttons collection of the

toolbarEach button can have its own look. The caption and the image are optional. Similar to the ListView and TreeView control, toolbar images are stored in an image list. The ToolBarButton class has an Index property which refers to the image in this list.

To display a tooltip for a button, set the ShowToolTips property to true. You can define the content of a tooltip by the ToolTipText property of the button.

Toolbar buttons can appear in different types. The Style property can be set to one of the ToolBarBuutonStyle values:

Value Description DropDownButton A drop-down control that displays a

menu or other window when clicked.

PushButton A standard, three-dimensional button.

Windows Forms 39

Separator A space or line between toolbar buttons. The appearance depends on the value of the Appearance property.

ToggleButton A toggle button that appears sunken when clicked and retains the sunken appearance until clicked again.

If you use the DropDownButton style, you must set the DropDownMenu property too. You must set the DropDownArrows property to true to see an arrow on the right side of the button.

If the user clicks on a button, a ButtonClick event is raised. This is a toolbar event, not a ToolBarButton event. The ToolBarButtonClickEventArgs argument contains a Button property, which indicates the clicked button. The ButtonDropDown event occurs when the arrow of a drop-down style ToolBarButton is clicked.

Because there is no event or another method to enable and disable the toolbar buttons, you must use another mechanism. The Application object offers the Idle event which occurs when the application has finished processing and is about to enter the idle state. You can handle this event to set the status of the toolbar buttons.

40 Windows Forms

Section 3: Using Controls

Common Dialogs

Windows offers some common dialogs. The .NET framework encapsulates this functionality in some classes. At the core, there is an abstract base class called CommonDialog. Derived from this class are:

Class DescriptionColorDialog Represents a common dialog box that

displays available colors along with controls that allow the user to define custom colors.

FontDialog Represents a common dialog box that displays a list of fonts that are currently installed on the system.

PageSetupDialog Represents a dialog box that allows users to manipulate page settings, including margins and paper orientation.

PrintDialog Allows users to select a printer and choose which portions of the document to print.

FileDialog Displays a dialog window from which the user can select a file. Derived from this class are OpenFileDialog, which represents a common dialog box that displays the control that allows the user to open a file and SaveFileDialog to saving a file.

Windows Forms 41

You display such a dialog by ShowDialog which returns a DialogResult value.

The FileOpenDialog offers the method OpenFile, which opens the file with read/write permission selected by the user. The return value is a Stream object. This is a simplification, otherwise you get the name of the file by the FileName property and open the file yourself. The OpenFileDialog class offers the OpenFile method too, but it opens the file selected by the user with read-only permission.

FontDialog raises the Apply event when the user clicks the Apply button. You can handle this event to preview the choosen font.

42 Windows Forms

Section 1: Using Controls

More controls

There some other controls, which will be described briefly.

TabControl and TabPageA tab control is analogous to the dividers in a notebook or the labels in a file cabinet. By using a tab control, an application can define multiple pages for the same area of a window or dialog box. Each page consists of a certain type of information or a group of controls that the application displays when the user selects the corresponding tab.

The .NET framework offers the TabControl for dividers and the TabPage controls for the individual pages. There are

TabControl tc = new TabControl();tc.Dock = DockStyle.Fill;tc.SelectedIndexChanged += new EventHandler( this.TabSelected );this.Controls.Add( tc );page1 = new TabPage("References");tc.TabPages.Add(page1);StatusBar and StatusBarPanelA status bar is a horizontal window at the bottom of a parent window in which an application can display various kinds of status information. The status bar can be divided into parts to display more than one type of information.

Windows Forms 43

The .NET framework offers the StatusBar control for the status bar and the StatusBarPanel control for individual panels. You create a panel by the Add method of the Panels collection. To display they panels, you must set the ShowPanels property to true. You can indicate the size and alignmen of each panel via some properties.

private StatusBar sb;private StatusBarPanel sbp0, sbp1;sb = new StatusBar();sbp0 = sb.Panels.Add("");sbp0.AutoSize = StatusBarPanelAutoSize.Contents;sbp1 = sb.Panels.Add("");sbp1.Text = “Panel Text”;sbp1.AutoSize = StatusBarPanelAutoSize.Contents;sbp1.Alignment = HorizontalAlignment.Center;sb.ShowPanels = true;Miscellaneous ControlsLinkLabel: Represents a Windows label control that can display hyperlinks.

ScrollBars: Implements the basic functionality of a scroll bar control. Derived from this abstract base class are VscrollBar and HscrollBar.

MonthCalendar: This control is an encapsulation of the Windows month calendar control.

DateTimePicker: Represents a Windows date-time picker control.

NumericUpDown: Represents a Windows up-down control that displays numeric values.

DomainUpDown: Represents a Windows up-down control that displays string values.

ProgressBar: Represents a Windows progress bar control.

TrackBar: The TrackBar is a scrollable control similar to the ScrollBar, but has a different UI. You can configure ranges through which it should scroll, and also define increments for off-button clicks. It can be aligned horizontally or vertically. You can also configure how many 'ticks' are shown for the total range of values.

PictureBox: Represents a Windows picture box control for displaying an image. Typically the PictureBox is used to display graphics from a bitmap, icon, JPEG, GIF or other image file types.

44 Windows Forms

Timer: Implements a timer that raises an event at user-defined intervals. This timer is optimized for use in Windows Forms applications and must be used in a window.

Windows Forms 45

Section 4: Data Bound Controls

Overview

Controls can be bound to data sources. This is true for most of the standard controls, as well as for the DataGrid control. DataGrid is a tabular control, comparable with the VB6 Flexgrid control. In addition to ADO.NET objects, you can bind arrays and some other framework classes to a DataGrid. Data binding is divided into two categories: simple and complex binding. But – contrary to what the terms simple and complex suggest – complex binding is easier to implement than simple binding. Simple binding means low level binding, complex binding means high level binding.

46 Windows Forms

Section 4: Data Bound Controls

ADO.NET: DataSets, DataTable and its familiy

ADO.Net is a new data access technology, which combine known features from ADO with new web-oriented aspects. In the center of ADO.NET is the DataSet class. You can look at a DataSet as an in memory database without a SQL engine. A DataSet is the container for tables, relations and some other familiar elements. But without a SQL engine, you can execute simple queries or filter and sort your data.

Tables are represented by DataTable objects, relations are implemented in DataRelation objects. There are classes for rows and columns: DataRow and DataColumn. DataTable offers properties to access a specific row or column. They offer method to add new rows, edit the content or select some rows. Events are raised to inform your application about these actions.

XML makes an important part of ADO.NET. You can load a XML document in a DataSet or store a DataSet as XML file. And you can use XML Schemas to define the structure of a DataSet.

A DataSet object is designed to be disconnected from a database. A DataSet is in-memory resident without a connection to a database or any other file. But ADO.NET supports connections to data sources too, to select, insert or update data in a database.

Windows Forms 47

Section 4: Data Bound Controls

Managed providers

The second core element in ADO.NET are the .NET Providers, which provide read/write access to, and interact between data sources (databases) and the DataSet.

NET providers consist of a set of objects that implement data source access. There are three components of a .NET provider implementation:

Connection, commands, and parameters that provide the interface between the data source and a DataSet object. The DataAdapter interface defines column and table mappings and loads a DataSet.

The data stream that provides high-performance access to data. This concept is implemented in the DataReader class, which reads a forward-only, read-only stream of data rows from a data source.

Low-level objects that connect to a database and execute database system specific commands.

The DataAdapter class is an important component of ADO.NET. It loads a DataSet and provides the bridge between the DataSet object and the data source by executing the appropriate SQL statements at the data source. ADO.NET features two providers:

OLE DB .NET Provider Manages communication between a table in a data set and a table or view in any data source that has an OLE DB provider. The OleDbDataAdapter object supports communication between a table within a DataSet and a

48 Windows Forms

table or view at the data source. The OLE DB .NET provider uses native OLE DB through COM Interop to enable data access.

SQL Client .NET Provider Manages communication between a table in a DataSet and a table or view in a SQL Server database. The SqlDataAdapter object mediates communication between a table within a DataSet and a table or view in a server database. The SQL Client .NET Provider uses its own protocol to communicate with SQL Server.

Windows Forms 49

Section 4: Data Bound Controls

Using the OLE DB .NET Provider

Working with a .NET managed provider is very similar to using ADO. There are even two different namespaces for OLE DB and the SQL Server, the procedure to read data from or update a database is the same. The connection string for a SQL Server connection includes no provider name, because the provider is fixed. The example code is based on an OLE DB connection.

First, you create an OleDbConnection object and open the connection.

CS = "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=X:\\ db.mdb;";OleDbConnection cn = new OleDbConnection(CS);cn.Open();Next you create a command object to query some data. The first argument includes a SQL Select statement, the second argument builds the connection.

OleDbCommand cmd = new OleDbCommand(selectstatement, cn);Now, you have a connection to the data source. Dependant on the application specific actions, you can choose between two methods to get the data. You can use the DataReader to retrieve a read-only, forward-only stream of data from the database. Using the DataReader can increase application performance and reduce system overhead because only one row at a time is ever in memory.

OleDbDataReader reader = cmd.ExecuteReader();

50 Windows Forms

while( reader.Read() ){ Console.WriteLine("{0} - {1}", reader[0], reader[1] ); // access the first two fields // of the current row}reader.Close();For broader operations you can use a data adapter to read all results in a DataSet. The OleDbDataAdapter class acts as a bridge between the data source and the DataSet. After creating a OleDbDataAdapter instance based on a command object, you can use its Fill method to transfer the data in the DataSet object. Because a DataSet can contain more than one table, the Fill method requires a table name. Fill gets back the number of rows read from the data source.

OleDbDataAdapter ada = new OleDbDataAdapter( cmd );DataSet ds = new DataSet();int n = ada.Fill( ds, tablename )DataTable tbl = ds.Tables[tablename]Finally you close the connection.

cn.Close();

Windows Forms 51

Section 4: Data Bound Controls

Data Binding

There are two types of binding: simple and complex. Simple data binding means a single value of a data source is bound to a control. Any property of a component can be bound to any value of a data source. For example you can bind the Text property of a TextBox to a column of a table. Complex data binding means a control is bound to a data source and examines and handles the structure by itsself. Examples for this category are the DataGrid and the ComboBox control.

Possible data sources are:

DataTable The representation of a table.

DataView A customized view of a single DataTable that may be filtered, searched, or sorted. A DataView is the data "snapshot" used by complex-bound controls.

DataSet The in-memory cache that consists of tables, relations, and constraints. In fact, you do not bound the entire DataSet, you bound one DataTable from a set.

DataSetView A customized view of the entire DataSet, analogous to a DataView, but with relations included.

Array An ordered collection of data contained in a variable and referenced by a single variable name. Each element of the array can be referenced by a numerical subscript.

52 Windows Forms

Collection An object that contains zero or more objects. Collections normally contain objects of the same class.

Windows Forms 53

Section 4: Data Bound Controls

Simple Binding

You can bind most of the Windows Forms controls to a data source. The Control class offers the DataBindings property that gets or sets a ControlBindingsCollection. This collection contains Binding objects, which represent the connection between a property of the control and a field of the data source. The following code binds the text property of two TextBox controls with a column of a DataTable. These columns are identified by its name – extension and description (see the example DBF4).

Each form can be bound to more than one data source. And each data source can be bound to many controls. The BindingContext of the Form class manages these bindings. For each data source bound to a Windows Form, a single BindingManagerBase exists. Because BindingManagerBase is an abstract base class, you never work with an instance of this class. Instead of that, BindingContext returns a CurrencyManager instance, which is derived from BindingManagerBase.

BindingManagerBase (and derived classes) offers a set of properties and methods to work with the data source. You can add new rows or navigate through the rows. Navigation is realized by the Position property. This property holds the index of the current row in the rows collection. You navigate to another row by setting the Position property to its index. You can determine the number of rows by the Count property of

54 Windows Forms

DataRowCollection or by the Count property of the BindingManagerBase object.

DataTable tbl;TextBox txtExt, txtDesc;// initialize these variables

private void Bind(){ txtExt.DataBindings.Add(new Binding("Text", tbl, "extension")); txtDesc.DataBindings.Add(new Binding("Text", tbl, "description"));

bmb = this.BindingContext[tbl];}

private void GoFirst(object sender, System.EventArgs e){ bmb.Position = 0;}

private void GoLast(object sender, System.EventArgs e){ bmb.Position = db.Table.Rows.Count-1;}

private void GoNext(object sender, System.EventArgs e){ if( bmb.Position < bmb.Count ) bmb.Position++;}

private void GoPrev(object sender, System.EventArgs e){

Windows Forms 55

if( bmb.Position > 0 ) bmb.Position--;}

56 Windows Forms

Section 4: Data Bound Controls

Complex Binding

Additionally to the Simple Data Binding process, there is Complex Binding. Instead of binding each data field to a separate control, you bind the complete data source to one control. A very useful component for complex data binding is the DataGrid Control.

Because a DataSet can contain more than one DataTable, there are two relevant properties: DataSource and DataMember. DataSource refers to the DataSet, DataMember refers to the contained DataTable. Alternatively you can use the SetDataBinding method, to set both values at once.

If you do not use a DataSet, you can leave the DataMember property by its default value – an empty string. If you use a DataTable as data source, it is sufficient to set the DataSource property.

class DBForm: Form{ private DataGrid grid; public DBForm(DB db) { grid = new DataGrid(); this.Controls.Add( grid ); grid.DataSource = db.Table; }

Windows Forms 57

}//class MyForm

58 Windows Forms

Section 5: User Controls

Overview

Writing a User Control for the .NET framework is straightforward: You derive a new class from an existing control class. The Windows Forms library is really object oriented and you can use most classes as base class for your own objects. Basically you can choose between three methods:

You derive a control from an existing standard control like TextBox or ListView.

You derive a control from the UserControl class and compose its functionality with other controls.

You derive your control from Control (or UserControl) and realize its functions from scratch.

For a better cooperation in a designer, you implement design time support. You can write type converters and/or type editors for user defined types or a special designer.

Windows Forms 59

Section 5: User Controls

Reusing existing elements

Extending existing controlsWindows Forms demonstrates the potential of an object oriented architecture – all GUI controls are derived from a common base class. Some of these controls have a larger family tree. DataGridTextBox is derived from TextBox, which is derived from TextBoxBase, which is derived from Control. VscrollBar is derived from ScrollBar, which is a child of Control.

For example, you can derive a class from ListView to realize a directory list:

public class DirView: ListView{ public DirView() { AddColumns(); // column headers Dir(“c:\\”); // DIR}DirView owns all the functionality from its base class ListView. It can use all public and protected elements and override the virtual functions. You have complex list functionality and must only add the DIR functions.

Composite controlsWhen the functions of one control are not sufficient, you can combine two or more controls. Suitable base classes for these controls are Panel or UserControl. The derived

60 Windows Forms

control acts as container for other controls. For example you can combine a Label and a TextBox to a “Labeled Textbox”.

class LabelTextBox: System.Windows.Forms.UserControl{ protected TextBox txt; protected Label lbl;}

Windows Forms 61

Section 5: User Controls

Custom Controls

Custom Controls are often derived from System.Windows.Form.Control. Because Control has no predefined display, your first step is to override OnPaint (or handle the Paint event). To interact with the user, you handle its mouse and keyboard input. You do that by overriding KeyDown, KeyUp and KeyPress and the Mouse functions like MouseDown. In some cases you must override IsInputKey or IsInputChar, otherwise your control does not receive key codes for the control keys.

You can add methods and properties to the control without restrictions. For a better integration in the design time environment you can assign some related attributes to the properties (see Design time support).

You can implement the optional methods ShouldSerializeXXX and ResetXXX to realize enhanced support for complex default values. XXX is a placeholder for the name of the affected property. ResetXXX sets a property to its default value. The ShouldSerializeXXX method is used by designers to check whether a property has changed from its default value. If true, the designer generates code.

Additionally, you can implement an event, which is raised when the value of a property has changed. This event should be named XXXChanged. It is good style to implement a corresponding overridable method, called OnXXXChanged.

You should use System.ComponentModel.EventHandler for events and System.ComponentModel.EventArgs for

62 Windows Forms

arguments. You can inherit an argument class from EventArgs to support specific values.

Windows Forms 63

Section 5: User Controls

Design time support (1)

Design-time functionality refers to the display and the behavior of a component or control in a visual designer. Design-time tasks include showing a component or control in a toolbox, displaying a component on a design surface, handling properties with non-standard types in a property browser, automatically generating code, and so on. The .NET Framework design-time architecture is flexible, and it is easy to extend and customize the base design-time functionality. For example, if you define a custom property on a control, you can easily provide a custom editor to edit that property in a property browser. Or, if you want to display a control in a special way at design time, you can use special classes called designers.

When you derive a component or control from a base component that has design-time attributes, your component inherits the design-time functionality of the base class. Only classes that directly or indirectly implement System.ComponentModel.IComponent have design-time support in a visual designer.

AttributesAttributes are the glue that binds design-time functionality to a component. In the .NET Framework, design-time functionality is implemented not within a component but outside the component, and it is associated with the component through metadata supplied by custom attributes.

64 Windows Forms

Browsable Specifies whether a property or an event should be displayed in the property browser.

Category Specifies the name of the category in which to group a property or event. When categories are used, component properties and events can be displayed in logical groupings in the property browser.

Description Defines a small block of text to be displayed at the bottom of the property browser when the user selects a property or event.

DefaultProperty Specifies the default property for the component. This property is selected in the property browser when a user clicks on the control.

DefaultValue Sets a simple default value for a property.

TypeConverter Specifies the type converter to use for converting the type of the property to another data type.

Editor Specifies the editor to use for editing (changing) a property in a visual designer.

RefreshProperties Indicates how a designer refreshes when the associated property value changes. This class cannot be inherited.

[TypeConverter(typeof(PercentConverter)),RefreshProperties(RefreshProperties.Repaint),Category("Layout"),Description("Label width in percent")]public Percent LabelPercent{// Code}

Windows Forms 65

Section 5: User Controls

Design time support (2)

Typically a property sheet supports input and editing of standard data types like strings, integers, booleans and so on. But in some cases your properties work with user defined datatypes. Now you need special mechanisms to use these values.

Type converterA Type Converter converts the value of an object to a different data type. A simple example is the conversion from a string to an integer and back. Type converters are primarily used for string-to-value conversions and for validation at design time and at run time. Most native data types (Int32, String, enumeration types, and others) have default type converters that provide string-to-value conversions and perform validation checks.

You can inherit your own type converter from an existing converter or from the base converter class TypeConverter. You must override some function, like CanConvertFrom and ConvertFrom to verify whether a type can be converted and to do the conversion.

public class PercentConverter: TypeConverter{ public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType ) { if( sourceType == typeof(string) ) return true;

66 Windows Forms

return base.CanConvertFrom( context, sourceType); }

public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value ) { if( value is string ) { return new Percent(Convert.ToUInt32(value)); } return base.ConvertFrom( context, culture, value); }}You use a converter via the TypeConverterAttribute attribute:

[ TypeConverter(typeof(MyTypeConverter))]public MyType PropertyName {...}

EditorIn some situations, a simple value-to-string conversion that allows a property to be displayed as text in the property browser might not be adequate. For instance, in the case of a color property, a visual representation is more desirable. A UI type editor allows such a representation and is intended for use with property browsers and other advanced design-time hosts.

To implement a custom UI type editor for Windows Forms, you

define a class that is derived from System.Drawing.Design.UITypeEditor.

override the EditValue method to set up properties of the user interface. This method is overloaded.

override the GetEditStyle method to inform the property browser about the editing support you will provide.

Windows Forms 67

Custom DesignersDesigners are classes that allow you to modify the design-time appearance and behavior of components and controls. Although the usual goal of any WYSIWYG form designer is to minimize differences between design-time and run-time appearance, at times special design-time cues are necessary. For example, a System.Windows.Forms.Panel object might not have a visible border at run time. However, without a border the panel is invisible to the developer designing a form that contains the panel. Therefore, the designer for the System.Windows.Forms.Panel object draws a dotted line border around the panel.

68 Windows Forms

Section 6: Miscellaneous

Overview

There are some additional features or aspects which should be described. Visual Basic 6 make extensive use of ActiveX Controls which should be further continue to be used.

Resources and enhanced message handling are additional subjects.

Windows Forms 69

Section 6: Miscellaneous

ActiveX Controls

You can use ActiveX Controls in your Windows Forms application. The .NET framework SDK contains some tools to work with COM/ActiveX Components. The ActiveX Control Importer (aximp.exe) converts type definitions in a COM type library for ActiveX Controls into a Windows Forms control. Windows Forms can only host Windows Forms controls. Aximp.exe generates a wrapper class for an ActiveX control that can be hosted on a Windows Form. This allows you to use the same design-time support and programming methodology applicable to other Windows Forms controls.

To generate a wrapper for an ActiveX Control call aximp with the filename as argument. Examples are:

aximp c:\winnt\system32\shdocvw.dllaximp c:\winnt\system32\mscal.ocxAximp generates some files, that contains .NET classes. You use one of these files only. AxSHDocVw.dll for the Webbrowser control or AxMSACAL.dll for the calendar control.

You must include these files in your project as reference. Additionally you should use a using (C#) or Imports (VB.NET) statement in your code, to refer the namespace.

Now you can create ActiveX Controls like other Controls. But there is one restriction. You must call the BeginInit method after creating the object and before you use any property or method. When you have finished the initialisation call EndInit. These two calls prevents the control from being used before it is fully initialized. In fact,

70 Windows Forms

if you do not call these methods, the ActiveX control is not succesfully created.

private AxWebBrowser wb;wb = new AxWebBrowser();wb.BeginInit();wb.Dock = DockStyle.Fill;wb.Visible = true;this.Controls.Add( wb );wb.EndInit();wb.GoHome();Additionally the Main function must use the attribute [STAThread()]. Without this attribute, you can’t use COM objects in your application.

Windows Forms 71

Section 6: Miscellaneous

Special message handling

Normally an application is informed about user input via the keyboard or the mouse by events. But in some cases it is helpful to get the raw Windows message before an event is raised. Windows Forms includes some concepts to support this.

IMessageFilter interfaceThis interface allows an application to capture a message before it is dispatched to a control or form. A class that implements the IMessageFilter interface can be added to the application's message pump to filter out a message or perform other operations before the message is dispatched to a form or control. To add the message filter to an application's message pump, use the AddMessageFilter method in the Application class.

For example the Windows.Forms.Splitter class implements this interface. Another example is a tracker, a set of handles around a control to resize it. The PreFilterMessage function is called before any event is raised. Therefore it simplifie the installation of a central message handler, which is responsible for all controls.

public class Tracker: IMessageFilter{ const int WM_MOUSEMOVE = 0x0200; bool IMessageFilter.PreFilterMessage( ref Message m )

72 Windows Forms

{ if( m.Msg == WM_MOUSEMOVE ) { // to something here } // ... WM_MOUSEDOWN, WM_MOUSEUP ...}

// Install the message filterTracker tr = new Tracker();Application.AddMessageFilter(tr);

PreProcessMessageThis function preprocesses input messages within the message loop before they are dispatched. This means, this function is called before any event (for example KeyDown) is raised. In some cases this functions call related functions like ProcessCmdKey, IsInputKey, IsInputChar or ProcessDialogKey. The function should return true if the method processes the message, otherwise false.

Windows Forms 73

Section 6: Miscellaneous

Related classes

KeysThe Key enumeration contains constants to use for processing keyboard input. This enumeration has a FlagsAttribute that allows the bitwise combination of its member values.

Examples are:

Alt The ALT modifier key.

Apps The Application key (Microsoft Natural Keyboard).

Back The BACKSPACE key.

C The C key.

Cancel The CANCEL key.

CapsLock The CAPS LOCK key.

Control The CTRL modifier key.

ControlKey The CTRL key.

CursorsThe Cursor class represents the image used to paint the mouse pointer. The Cursors class provides a collection of Cursor objects for use by a Windows Forms application.

Examples are:

AppStarting Gets the cursor that appears as an application is starting.

74 Windows Forms

Arrow Gets the arrow cursor.

Cross Gets the crosshair cursor.

Default Gets the default cursor, which is usually an arrow cursor.

System InformationThe SystemInformation class provides information about the operating system. SystemInformation provides static (Shared) methods and properties that can be used to get information such as Windows display element sizes, operating system settings, network availability, and the capabilities of hardware installed on the system. This class cannot be instantiated.

Examples are:

BorderSize Gets the width and height of a window border in pixels.

MenuHeight Gets the height of one line of a menu in pixels.

SmallIconSize Gets the recommended dimensions of a small icon in pixels.

UserName Gets the user name for the current thread, that is, the name of the user currently logged onto the system.

GetFolderPath Gets the path to a specific special folder.

Windows Forms 75

Section 6: Miscellaneous

Resources

A resource is any nonexecutable piece of data that is logically deployed with an application. Resources can contain data in a number of forms, including strings, images, and persisted objects. You can localize resources for specific cultures. This allows a user of your application to easily change computer settings through Control Panel. Based on the user’s culture selection, the appropriate set of resources is retrieved. The CultureInfo.CurrentUICulture Property specifies the user’s culture. The CultureInfo.CurrentUICulture property is available only in the International version of Windows. However, you can write application code to make the user’s culture selection available in different ways.

You can deploy resources in satellite assemblies. By definition, satellite assemblies only contain resource files.

.NET uses a new file format for resources. You can create a .resource file with the SDK commandline tool ResGen. The samples contains a graphical editor for .resx and .resource files. You can link a resource to the programm or component or you can use a separate .resource file.

You load a separate file by a ResourceManager object. Its CreateFileBasedResourceManager method loads a resource file. The first argument is the root name of the ressource: res for res.resource. The second argument indicates the directory, in this case the program folder. Additionally you can indicate a ResourceSet or null for the default set.

76 Windows Forms

ResourceManager offers some methods to read single resources. GetString reads a string resource, GetObject any other type like an icon or a bitmap.

ResourceManager rm = ResourceManager.CreateFileBasedResourceManager ( "res", ".", null );this.Text = rm.GetString("Title");this.Icon = (Icon)rm.GetObject("AppIcon");You can link an icon directly in the application code. The explorer displays this icon as program icon. The commandline compiler option for such an icon is

/win32icon:netfx.icoIf you want to use this icon in you code, you must link it with the /resource option.

/resource:netfx.icoNow you can read it from the assembly:

this.Icon = new Icon(GetType().Module.Assembly. GetManifestResourceStream("netfx.ico"));

Windows Forms 77

Summary

SummaryWindows Forms is a straightforward and really object oriented GUI library. It offers many feature rich classes which are easy to use. It is one common library for all.NET languages.