Chapter 13. Building Windows Applications

The previous chapters have used console applications to demonstrate C# and the Common Language Runtime. Although console applications can be implemented simply, it is time to turn your attention to the reason you’re learning the C# language in the first place: building Windows and web applications.

In the early days of Windows computing, an application ran on a desktop, in splendid isolation. Over time, developers found it beneficial to spread their applications across a network, with the user interface on one computer and a database on another. This division of responsibilities or partitioning of an application came to be called two-tier or client-server application development. Later three-tier or n-tier approaches emerged as developers began to use web servers to host business objects that could handle the database access on behalf of clients.

When the Web first came along, there was a clear distinction between Windows applications and web applications. Windows applications ran on the desktop or a local-area network (LAN), and web applications ran on a distant server and were accessed by a browser. This distinction is now being blurred as Windows applications reach out to the Web for services. Many new applications consist of logic running on a client, a database server, and remote third-party computers located on the Web. Traditional desktop applications such as Excel or Outlook are now able to integrate data retrieved through web connections seamlessly, and web applications can distribute some of their processing to client-side components.

The primary remaining distinction between a Windows application and a web application might be this: who owns the user interface? Will your application use a browser to display its user interface, or will the UI be built into the executable running on the desktop?

There are enormous advantages to web applications, starting with the obvious: they can be accessed from any browser that can connect to the server. In addition, updates can be made at the server, without the need to distribute new dynamic link libraries (DLLs) to your customers.

On the other hand, if your application derives no benefit from being on the Web, you might find that you can achieve greater control over the look and feel of your application, or you can achieve better performance, by building a desktop application.

.NET offers closely related, but distinguishable, suites of tools for building Windows or web applications. Both are based on forms, with the premise that many applications have user interfaces centered on interacting with the user through forms and controls, such as buttons, list boxes, text, and so forth.

The tools for creating web applications are called Web-Forms and are considered in Chapter 15. The tools for creating Windows applications are called Windows Forms and are the subject of this chapter.

Tip

It is my prediction that the distinction between Web-Forms and Windows Forms is temporary. There is such obvious similarity between these two approaches that I’d be very surprised if the next version of .NET didn’t merge these two tools into one unified development environment.

In the following pages, you will learn how to create a simple Windows Form using either a text editor such as Notepad or the Design tool in Visual Studio.NET. Next you will build a more complex Windows application using Visual Studio, the Windows Forms framework, and a number of C# programming techniques you learned in earlier chapters. The chapter concludes with a brief introduction to Documentation Comments, a new XML-facilitated means to document applications, and an introduction to the deployment of .NET applications.

Creating a Simple Windows Form

A Windows Form is a tool for building a Windows application. The .NET Framework offers extensive support for Windows application development, the centerpiece of which is the Windows Forms framework. Not surprisingly, Windows Forms use the metaphor of a form. This idea was borrowed from the wildly successful Visual Basic (VB) environment and supports Rapid Application Development (RAD). Arguably, C# is the first development environment to marry the RAD tools of Visual Basic with the object-oriented and high-performance characteristics of a C-family language.

Using Notepad

Visual Studio.NET provides a rich set of drag-and-drop tools for working with Windows Forms. It is possible to build a Windows application without using the Visual Studio Integrated Development Environment (IDE), but it is far more painful and takes a lot longer.

However, just to prove the point, you’ll use Notepad to create a simple Windows Form application that displays text in a window and implements a Cancel button. The application display is shown in Figure 13-1.

The hand-drawn Windows Form

Figure 13-1. The hand-drawn Windows Form

You start by adding a using statement for the Windows Forms namespace:

using System.Windows.Forms;

The key to creating a Windows Form application is to derive your form from System.Windows.Forms.Form:

public class HandDrawnClass : Form

The Form object represents any window displayed in your application. You can use the Form class to create standard windows, as well as floating windows, tools, dialog boxes, and so forth. Microsoft apparently chose to call this a form rather than a window to emphasize that most windows now have an interactive component that includes controls for interacting with users.

All the Windows widgets you’ll need (labels, buttons, list boxes, etc.) are found within the Windows.Forms namespace. In the IDE, you’ll be able to drag and drop these objects onto a designer, but for now you’ll declare them right in your program code.

To get started, declare the two widgets you need, a label to hold the Hello World text and a button to exit the application:

private System.Windows.Forms.Label lblOutput;
private System.Windows.Forms.Button btnCancel;

You’re now ready to instantiate these objects, which you do in your Form’s constructor:

this.lblOutput = new System.Windows.Forms.Label(  );
this.btnCancel = new System.Windows.Forms.Button(  );

Next you can set the Form’s title text to Hello World:

this.Text = "Hello World";

Tip

Note that the preceding statements appear in your form’s constructor, HandDrawnClass, and so the this keyword refers to the form itself.

Set the label’s location, text, and size:

lblOutput.Location = new System.Drawing.Point (16, 24);
lblOutput.Text = "Hello World!";
lblOutput.Size = new System.Drawing.Size (216, 24);

The location is expressed as a System.Drawing.Point object, whose constructor takes a horizontal and vertical position. The size is set with a Size object, whose constructor takes a pair of integers that represent the width and height of the object.

Tip

The .NET Framework provides the System.Drawing object, which encapsulates the Win32 GID+ graphics functions. Much of the .NET Framework Class Library ( FCL) consists of classes that encapsulate Win32 methods as objects.

Next, do the same for the button object, setting its location, size, and text:

btnCancel.Location = new System.Drawing.Point (150,200);
btnCancel.Size = new System.Drawing.Size (112, 32);
btnCancel.Text = "&Cancel";

The button also needs an event handler. As described in Chapter 12, events (in this case the cancel button-click event) are implemented using delegates. The publishing class (button) defines a delegate (System.EventHandler) that the subscribing class (your form) must implement.

The delegated method can have any name but must return void and take two parameters: an object (sender) and a SystemEventArgs object, typically named e:

protected void btnCancel_Click (
       object sender, System.EventArgs e)
{
   //...
}

You register your event handler method in two steps. First you create a new System.EventHandler delegate, passing in the name of your method as a parameter:

new System.EventHandler (this.btnCancel_Click);

You then add that delegate to the button’s click event handler list with the += operator.

The following line combines these steps into one:

one:btnCancel.Click += 
    new System.EventHandler (this.btnCancel_Click);

Now you must set up the form’s dimensions. The form property AutoScaleBaseSize sets the base size used at display time to compute the scaling factor for the form. The ClientSize property sets the size of the form’s client area, which is the size of the form excluding borders and titlebar (when you use the designer, these values are provided for you interactively):

this.AutoScaleBaseSize = new System.Drawing.Size (5, 13);
this.ClientSize = new System.Drawing.Size (300, 300);

Finally, remember to add the widgets to the form:

this.Controls.Add (this.btnCancel);
this.Controls.Add (this.lblOutput);

Having registered the event handler, you must supply the implementation. For this example, clicking Cancel will exit the application, using the static method Exit( ) of the Application class:

protected void btnCancel_Click (
  object sender, System.EventArgs e)
{
   Application.Exit (  );
}

That’s it; you just need an entry point to invoke the constructor on the form:

public static void Main(  ) 
{
    Application.Run(new HandDrawnClass(  ));
}

The complete source is shown in Example 13-1. When you run this application, the window is opened and the text is displayed. Pressing Cancel closes the application.

Example 13-1. Creating a hand-drawn Windows Form

using System;
using System.Windows.Forms;

namespace ProgCSharp
{
   public class HandDrawnClass : Form
   {
      // a label to display Hello World
      private System.Windows.Forms.Label 
         lblOutput;

      // a cancel button
      private System.Windows.Forms.Button 
         btnCancel;

      public HandDrawnClass(  )
      {
         // create the objects
         this.lblOutput = 
            new System.Windows.Forms.Label (  );
         this.btnCancel = 
            new System.Windows.Forms.Button (  );

         // set the form's title
         this.Text = "Hello World";

         // set up the output label
         lblOutput.Location = 
            new System.Drawing.Point (16, 24);
         lblOutput.Text = "Hello World!";
         lblOutput.Size = 
            new System.Drawing.Size (216, 24);

         // set up the cancel button
         btnCancel.Location = 
            new System.Drawing.Point (150,200);
         btnCancel.Size = 
            new System.Drawing.Size (112, 32);
         btnCancel.Text = "&Cancel";
            
         // set up the event handler
         btnCancel.Click += 
            new System.EventHandler (this.btnCancel_Click);

         // Add the controls and set the client area
         this.AutoScaleBaseSize = 
            new System.Drawing.Size (5, 13);
         this.ClientSize = 
            new System.Drawing.Size (300, 300);
         this.Controls.Add (this.btnCancel);
         this.Controls.Add (this.lblOutput);

      }

      // handle the cancel event
      protected void btnCancel_Click (
         object sender, System.EventArgs e)
      {
         Application.Exit(  );
      }

      // Run the app
      public static void Main(  ) 
      {
         Application.Run(new HandDrawnClass(  ));
      }
   }
}

Using the Visual Studio.Net Designer

Although hand coding is always great fun, it is also a lot of work, and the result in the previous example is not as elegant as most programmers would expect. The Visual Studio IDE provides a design tool for Windows Forms that is much easier to use.

To begin work on a new Windows application, first open Visual Studio and choose New Project. In the New Project window, create a new C# Windows application and name it ProgCSharpWindowsForm, as shown in Figure 13-2.

Creating a Windows Form application

Figure 13-2. Creating a Windows Form application

Visual Studio responds by creating a Windows Form application and, best of all, putting you into a design environment as shown in Figure 13-3.

The design environment

Figure 13-3. The design environment

The Design window displays a blank Windows Form (Form1). A Toolbox window is also available, with a selection of Windows widgets and controls. If the Toolbox is not displayed, try clicking the word “Toolbox,” or select View Toolbox on the Visual Studio menu. You can also use the keyboard shortcut Ctrl-Alt-X to display the Toolbox. With the Toolbox displayed, you can drag a label and a button directly onto the form, as shown in Figure 13-4.

The Windows Form development environment

Figure 13-4. The Windows Form development environment

Before proceeding, take a look around. The Toolbox is filled with controls that you can add to your Windows Form application. In the upper-right corner you should see the Solution Explorer, a window which displays all the files in your projects. In the lower-right corner is the Properties window, which displays all the properties of the currently selected item. In Figure 13-4, the label (label1) is selected, and the Properties window displays its properties.

You can use the Properties window to set the static properties of the various controls. For example, to add text to label1, you can type the words “Hello World” into the box to the right of its Text property. If you want to change the font for the lettering in the HelloWorld label, you click the Font property shown in the lower-right corner of Figure 13-5. (You can provide text in the same way for your button (button1) by selecting it in the Property window and typing the word “Cancel” into its Text property.)

Modifying the font

Figure 13-5. Modifying the font

Any one of these steps is much easier than modifying these properties in code (though that is certainly still possible).

Once you have the form laid out the way you want, all that remains is to create an event handler for the Cancel button. Double-clicking the Cancel button will create the event handler, register it, and put you on the code-behind page (the page that holds the source code for this form), where you can enter the event handling logic, as shown in Figure 13-6.

After double-clicking the Cancel button

Figure 13-6. After double-clicking the Cancel button

The cursor is already in place; you have only to enter the one line of code:

Application.Exit(  );

Tip

In the IDE, the cursor flashes, making it very easy to see where the code goes. For most readers, the cursor probably will not flash in this book.

Visual Studio.NET generates all the code necessary to create and initialize the components. The complete source code is shown in Example 13-2, including the one line of code you provided (shown in bold in this example) to handle the Cancel button-click event.

Example 13-2. Source code generated by the IDE

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace ProgCSharpWindowsForm
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
      private System.Windows.Forms.Label lblOutput;
      private System.Windows.Forms.Button btnCancel;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container 
         components;

        public Form1(  )
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent(  );

            //
            // TODO: Add any constructor code 
         // after InitializeComponent call
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        public override void Dispose(  )
        {
            base.Dispose(  );
            if(components != null)
                components.Dispose(  );
        }

        #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.lblOutput = new System.Windows.Forms.Label(  );
         this.btnCancel = new System.Windows.Forms.Button(  );
         this.SuspendLayout(  );
         // 
         // lblOutput
         // 
         this.lblOutput.Font = new System.Drawing.Font("Arial", 15.75F, 
            System.Drawing.FontStyle.Bold, 
            System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
         this.lblOutput.Location = new System.Drawing.Point(24, 16);
         this.lblOutput.Name = "lblOutput";
         this.lblOutput.Size = new System.Drawing.Size(136, 48);
         this.lblOutput.TabIndex = 0;
         this.lblOutput.Text = "Hello World";
         // 
         // btnCancel
         // 
         this.btnCancel.Location = new System.Drawing.Point(192, 208);
         this.btnCancel.Name = "btnCancel";
         this.btnCancel.TabIndex = 1;
         this.btnCancel.Text = "Cancel";
         this.btnCancel.Click += new System.EventHandler(
            this.btnCancel_Click);
         // 
         // Form1
         // 
         this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
         this.ClientSize = new System.Drawing.Size(292, 273);
         this.Controls.AddRange(new System.Windows.Forms.Control[] {
                   this.btnCancel, this.lblOutput});
         this.Name = "Form1";
         this.Text = "Form1";
         this.ResumeLayout(false);

      }

      private void btnCancel_Click(object sender, System.EventArgs e)
      {
         Application.Exit(  );
      }

        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(  ) 
        {
            Application.Run(new Form1(  ));
        }


    }
}

Tip

Some of the code in this listing has been reformatted to fit the printed page.

There is quite a bit of code in this listing that did not appear in; though most of it is not terribly important. When Visual Studio creates the application, it must add some boilerplate code that is not essential for this simple application.

A careful examination reveals that the essentials are the same, but there are some key differences worth examining. The listing starts with special comment marks:

/// <summary>
/// Summary description for Form1.
/// </summary>

These marks are used for creating documentation; they are explained in detail later in this chapter.

The form derives from System.Windows.Forms.Form as did our earlier example. The widgets are defined as in the previous example:

public class Form1 : System.Windows.Forms.Form
{
   private System.Windows.Forms.Label lblOutput;
   private System.Windows.Forms.Button btnCancel;

The designer creates a private container variable for its own use:

private System.ComponentModel.Container 
   components;

In this and in every Windows Form application generated by Visual Studio .NET, the constructor calls a private method, InitializeComponent( ) , which is used to define and set the properties of all the controls. The properties are set based on the values you’ve chosen (or on the default values you’ve left alone) in the designer. The InitializeComponent( ) method is marked with a comment that you should not modify the contents of this method; making changes to this method might confuse the designer.

This program will behave exactly as your earlier hand-crafted application did.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.165.62