Developing Windows Forms Applications






Developing Windows Forms Applications

The Visual Studio .NET Windows Forms designer enables drag-and-drop development of Windows forms applications. Also known as WinForms, these applications manifest all or part of their user interface as windows on the desktop.

The process of building a Windows Forms application starts the same as all other project types within Visual Studio: You select the Windows Application project template from the New Project dialog box and set up the location for the applications source. From there, Visual Studio will stub out an initial project, and the Windows Forms designer will load, as shown in Figure.

29. Initial form in the Windows Forms designer.


As you can see from the figure, a design-time "mock up" of the actual form is visible within the designer. This is the canvas for your user interface. Using this canvas, you can add controls and visual elements to the form, tweak the look and feel of the form itself, and launch directly to the code that is wired to the form. Changes made in the designer are actually implemented as changes made to the form's resource file (.resx). In other words, the designer is really an XML editor with a graphical presentation; behind the scenes, it is manipulating the form's underlying XML description in order to visually realize the form that you see within the designer.

To investigate how the designer works, start with a simple design premise: Say you want to take the blank form that Visual Studio generated for you and create a login dialog box that allows users to input a name and password and confirm their entries by clicking an OK button. A Cancel button should also be available to allow users to dismiss the form.

Note

Don't get confused about the various representations that a form can have, such as message box or dialog box. From a development perspective, they are all windows and are therefore all forms.


The designer in this exercise allows you, the developer, to craft the form and its actions while writing as little code as possible. Using drag-and-drop operations and Property dialog boxes, you should be able to customize the look and feel of the application without ever dealing with the code editor.

Customizing the Form's Appearance

There are a few obvious visual elements in the designer. For one, the form itself is shown complete with borders, title bar, client area, and Min/Max/Close buttons. In addition, you can see grab handles at the corners of the form and at the 12, 3, 6, and 9 o'clock positions. The grab handles are used to resize the form. To change other attributes of the form, you use the property grid for the form. The property grid will allow you to set the background color, border appearance and behavior, title text, and so on.

In Figure, the title of the form has been changed to Login, and the border behavior has been changed to match a dialog box as opposed to a normal, resizable window.

30. Editing the form's size and title.


Adding Controls to a Form

Controls are adornments to a form that have their own user interface. (There is such a thing as UI-less controls; we'll cover such controls in this chapter when we discuss component design.) They provide the principal interaction mechanism method with a form. Put another way, a form is really just a container for the various controls that will implement the desired functionality for the form.

You can add controls to a form quite easily by dragging and dropping them from the Toolbox. Continuing the metaphor of the designer as a canvas, the Toolbox is the palette.

The Toolbox

The Toolbox is a dockable window within the IDE; it is viewable only when you are editing a project element that supports Toolbox functionality. To make sure the Toolbox is visible, select it from the View menu (or use the Ctrl+W, X shortcut).

The Toolbox groups the controls in a tabbed tree. Simply expand the tab grouping (such as Common Controls or Menus & Toolbars), and you will see a list of the available controls. In this case, you want two text box controls to hold the login ID and password text, a few label controls to describe the text box controls, and the OK and Cancel buttons to commit or cancel the entries. All of these controls can be located under the Common Controls tab (see Figure)

31. The Toolbox.


To place a control on the form, drag its representation from the Toolbox onto the form. Some controls, referred to as components, don't actually have a visual user interface. The timer is one example of a component. When you drag a component to a form, it is placed in a separate area of the designer called the component tray. The component tray allows you to select one of the added components and access its properties via the Properties window.

Arranging Controls

When you are designing a form, control layout becomes an important issue. You are typically concerned about ensuring that controls are aligned either horizontally or vertically, that controls and control groups are positioned with equal and common margins between their edges, that margins are enforced along the form borders, and so on.

The designer provides three distinct sets of tools and aids that assist with form layout. First, you have the options available to you under the Format menu. With a form loaded in the designer, you can select different groups of controls and use the commands under the Format menu to align these controls vertically or horizontally with one another, standardize and increase or decrease the spacing between controls, center the controls within the form, and even alter the controls' appearance attributes so that they are of equal size in either dimension.

The other layout tools within the designer are interactive in nature and are surfaced through two different modes: snap line and grid positioning. You can toggle between these two modes via the Windows Forms Designer Options dialog box (choose Tool, Options and then the Windows Forms Designer tab). The property called LayoutMode can be set to either SnapToGrid or SnapLines.

Using the Layout Grid

The layout grid is, as its name implies, a grid that is laid on top of the form. The grid itself is visually represented within the designer by dots representing the intersection of the grid squares. As you drag and move controls over the surface of the grid, the designer will automatically snap the control's leading edges to one of the grid's square edges.

Tip

Even with the grid layout turned on, you can circumvent the snapping behavior by selecting a control, holding down the Ctrl key, and using the arrow keys to move the control up, down, right, or left one pixel at a time.


The size of the grid squares (and thus the spacing of these guide dots) is controlled by the GridSize property (also located in the Options dialog box). A smaller grid size equates to a tighter spacing of guide dots, which in turns equates to more finely grained control over control placement.

Figure shows the login form with the layout grid in evidence. Note that the grid was used to make sure that

32. The layout grid.


  • The text boxes are aligned with one another (and are the same length).

  • The labels are aligned vertically with the text boxes and horizontally with each other.

  • The buttons are aligned vertically and have an appropriate buffer area between their control edges and the form's border.

Using Snap Lines

Snap lines are a slightly more intelligent mechanism for positioning controls. With snap lines, there is no grid visible on the form's surface. Instead, the designer draws visual hints while a control is in motion on the form.

Figure illustrates snap lines in action; this figure shows the process of positioning the OK button.

33. Using snap lines.


Note that the control has "snapped" into a position that is located a set distance away from the form border (indicated by the thin blue line extending down from the button to the form edge). The button snap position also sufficiently spaces the control from its neighboring Cancel button, as indicated by the thin blue line extending from the right edge of the button to the left edge of the Cancel button. The snap line algorithm has also determined that you are trying to create a row of buttons and thus need to vertically align the current control to its neighbor. This is actually done using the interior text of the buttons; the thin pink line running under the text of both buttons clearly shows that they are perfectly aligned.

The snap line algorithms automatically take into account the recommended margins and spacing distances as discussed in the Windows User Interface Guidelines adopted by Microsoft. This feature takes the guesswork out of many layout decisions and helps to ensure some commonality and standards adherence within the Windows Forms applications.

Note

Changes made to the layout modes of the designer typically do not take effect immediately. You may need to close the designer and reopen it after making a change (such as switching between SnapLine mode and SnapToGrid mode).


Resizing Controls and Editing Attributes

When a control is in place on its parent form, you can interact with the control in various ways. You can set control properties using the Properties window. You also can alter the sizing and shape of the control by dragging the grab handles on the sides of the control.

Writing Code

Although the designer excels at enabling developers to visually construct a user interface, its ability to actually implement behavior is limited. You can use the designer to place a button, but responding to a click on the button and reacting in some way are still the domain of code.

At the code level, a form is simply a class that encapsulates all of the form's behavior. For simplicity and ease of development, Visual Studio pushes all of the code that it writes via the designer into clearly marked regions and, in the case of Windows forms, a separate code file. The file is named after the primary form code file like this: <FormName>.Designer.<language extension>. As an example, the login form is accompanied by a Login.Designer.cs file that implements the designer-written code.

Listing 6.1 shows what Visual Studio has generated in the way of code to implement the changes made through the designer.

Windows Forms DesignerGenerated Code

namespace Contoso.UI.WindowsForms.OrderEntry
{
    partial class Login
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed;
        /// otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
           if (disposing && (components != null))
           {
               components.Dispose();
           }
           base.Dispose(disposing);
       }

       #region Windows Form Designer generated code

       /// <summary>
       /// Required method for Designer support - do not modify
       /// the contents of this method with the code editor.
       /// </summary>
       private void InitializeComponent()
       {
           this.label1 = new System.Windows.Forms.Label();
           this.label2 = new System.Windows.Forms.Label();
           this.textBoxID = new System.Windows.Forms.TextBox();
           this.textBoxPassword = new System.Windows.Forms.TextBox();
           this.buttonCancel = new System.Windows.Forms.Button();
           this.buttonOk = new System.Windows.Forms.Button();
           this.SuspendLayout();
           //
           // label1
           //
           this.label1.AutoSize = true;
           this.label1.Location = new System.Drawing.Point(61, 23);
           this.label1.Name = "label1";
           this.label1.Size = new System.Drawing.Size(17, 13);
           this.label1.TabIndex = 0;
           this.label1.Text = "ID:";
           //
           // label2
           //
           this.label2.AutoSize = true;
           this.label2.Location = new System.Drawing.Point(26, 46);
           this.label2.Name = "label2";
           this.label2.Size = new System.Drawing.Size(52, 13);
           this.label2.TabIndex = 1;
           this.label2.Text = "Password:";
           //
           // textBoxID
           //
           this.textBoxID.Location = new System.Drawing.Point(85, 20);
           this.textBoxID.Name = "textBoxID";
           this.textBoxID.Size = new System.Drawing.Size(195, 20);
           this.textBoxID.TabIndex = 2;
           //
           // textBoxPassword
           //
           this.textBoxPassword.Location = new System.Drawing.Point(85, 46);
           this.textBoxPassword.Name = "textBoxPassword";
           this.textBoxPassword.Size = new System.Drawing.Size(195, 20);
           this.textBoxPassword.TabIndex = 3;
           //
           // buttonCancel
           //
           this.buttonCancel.DialogResult =
              System.Windows.Forms.DialogResult.Cancel;
           this.buttonCancel.Location = new System.Drawing.Point(205, 72);
           this.buttonCancel.Name = "buttonCancel";
           this.buttonCancel.Size = new System.Drawing.Size(75, 23);
           this.buttonCancel.TabIndex = 4;
           this.buttonCancel.Text = "Cancel";
           //
           // buttonOk
           //
           this.buttonOk.Location = new System.Drawing.Point(124, 72);
           this.buttonOk.Name = "buttonOk";
           this.buttonOk.Size = new System.Drawing.Size(75, 23);
           this.buttonOk.TabIndex = 5;
           this.buttonOk.Text = "OK";
           //
           // Login
           //
           this.AcceptButton = this.buttonOk;
           this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
           this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
           this.CancelButton = this.buttonCancel;
           this.ClientSize = new System.Drawing.Size(292, 109);
           this.Controls.Add(this.buttonOk);
           this.Controls.Add(this.buttonCancel);
           this.Controls.Add(this.textBoxPassword);
           this.Controls.Add(this.textBoxID);
           this.Controls.Add(this.label2);
           this.Controls.Add(this.label1);
           this.FormBorderStyle =
               System.Windows.Forms.FormBorderStyle.FixedDialog;
           this.MaximizeBox = false;
           this.MinimizeBox = false;
           this.Name = "Login";
           this.ShowInTaskbar = false;
           this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
           this.Text = "Login";
           this.ResumeLayout(false);
           this.PerformLayout();

       }

       #endregion

       private System.Windows.Forms.Label label1;
       private System.Windows.Forms.Label label2;
       private System.Windows.Forms.TextBox textBoxID;
       private System.Windows.Forms.TextBox textBoxPassword;
       private System.Windows.Forms.Button buttonCancel;
       private System.Windows.Forms.Button buttonOk;
   }

}



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows