Previous Section  < Day Day Up >  Next Section

6.3. The Form Class

The Form object inherits all the members of the Control class as well as the ScrollableControl class, which provides properties that enable scrolling. To this it adds a large number of properties that enable it to control its appearance, work with child forms, create modal forms, display menus, and interact with the desktop via tool and status bars. Table 6-5 shows a selected list of these properties.

Table 6-5. Selected Form Properties






Gets or sets the border style of the form. It is defined by the FormBorderStyle enumeration:

Fixed3D        None

FixedSingle    Sizable



Boolean value that determines whether the menu icon in the left corner of a form and the close button on the upper right are shown.



Boolean value that indicates whether these buttons are displayed on the form.


Gets or sets the opacity of the form and all of its controls. The maximum value (least transparent) is 1.0. Does not work with Windows 95/98.


A color that represents transparent areas on the form. Any control or portion of the form that has a back color equal to this color is not displayed. Clicking this transparent area sends the event to any form below it.

Size and position


Indicates whether the form adjusts its size to accommodate the size of the font used.


Size of the form excluding borders and the title bar.


A Point type that indicates where the form is located on the desktop window.


Specifies the initial position of a form. It takes a FormStartPosition enum value:

CenterParent? Centered within bounds of parent form.

CenterScreen? Centered within the display.

Manual? Use the DeskTopLocation value.

Windows DefaultLocation? Windows sets value.



A Size object that designates the maximum and minimum size for the form. A value of (0,0) indicates no minimum or maximum.


Boolean value specifying whether application is represented in Windows task bar. Default is true.



Indicates whether to display the form as a TopLevel window or TopMost window. A top-level window has no parent; top-most form is always displayed on top of all other non-TopMost forms.


Indicates how the form is displayed on startup. It takes a value from the FormWindowState enumeration: Maximized, Minimized, or Normal.

Owner forms


The form designated as the owner of the form.


A Form array containing the forms owned by a form.

Setting a Form's Appearance

The four properties shown in Figure 6-6 control which buttons and icon are present on the top border of a form. The Icon property specifies the .ico file to be used as the icon in the left corner; the ControlBox value determines whether the icon and close button are displayed (true) or not displayed (false); similarly, the MaximizeBox and MinimizeBox determine whether their associated buttons appear.

Figure 6-6. Properties to control what appears on the title bar

The purpose of these properties is to govern functionality more than appearance. For example, it often makes sense to suppress the minimize and maximize buttons on modal forms in order to prevent a user from maximizing the form and hiding the underlying parent form.

Form Opacity

A form's opacity property determines its level of transparency. Values ranges from 0 to 1.0, where anything less than 1.0 results in partial transparency that allows elements beneath the form to be viewed. Most forms work best with a value of 1.0, but adjusting opacity can be an effective way to display child or TopMost forms that hide an underlying form. A common approach is to set the opacity of such a form to 1.0 when it has focus, and reduce the opacity when it loses focus. This technique is often used with search windows that float on top of the document they are searching.

Let's look at how to set up a form that sets its opacity to 1 when it is active and to .8 when it is not the active form. To do this, we take advantage of the Deactivate and Activated events that are triggered when a form loses or gains focus. We first set up the delegates to call the event handling routines:

this.Deactivate += new System.EventHandler(Form_Deactivate);

this.Activated  += new System.EventHandler(Form_Activate);

The code for the corresponding event handlers is trivial:

void Form_Deactivate(object sender, EventArgs e)

{   this.Opacity= .8;   }

void Form_Activate(object sender, EventArgs e)

{   this.Opacity= 1;   }

Form Transparency

Opacity affects the transparency of an entire form. There is another property, TRansparencyKey, which can be used to make only selected areas of a form totally transparent. This property designates a pixel color that is rendered as transparent when the form is drawn. The effect is to create a hole in the form that makes any area below the form visible. In fact, if you click a transparent area, the event is recognized by the form below.

The most popular use of transparency is to create non-rectangular forms. When used in conjunction with a border style of FormBorderStyle.None to remove the title bar, a form of just about any geometric shape can be created. The next example illustrates how to create and use the cross-shaped form in Figure 6-7.

Figure 6-7. Form using transparency to create irregular appearance

The only requirement in creating the shape of the form is to lay out the transparent areas in the same color as the transparency key color. Be certain to select a color that will not be used elsewhere on the form. A standard approach is to set the back color of the form to the transparency key color, and draw an image in a different color that it will appear as the visible form.

To create the form in Figure 6-7, place Panel controls in each corner of a standard form and set their BackColor property to Color.Red. The form is created and displayed using this code:

CustomForm myForm = new CustomForm();

myForm.TransparencyKey = Color.Red;

myForm.FormBorderStyle= FormBorderStyle.None;


This achieves the effect of making the panel areas transparent and removing the title bar. With the title bar gone, it is necessary to provide a way for the user to move the form. This is where the mouse event handling discussed earlier comes to the rescue.

At the center of the form is a multiple arrow image displayed in a PictureBox that the user can click and use to drag the form. Listing 6-4 shows how the MouseDown, MouseUp, and MouseMove events are used to implement form movement.

Listing 6-4. Using Form Transparency to Create a Non-Rectangular Form

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

public class CustomForm : Form    


   private Point lastPoint = Point.Empty;  //Save mousedown

   public CustomForm()


      InitializeComponent();  // set up form

      //Associate mouse events with pictureBox

      pictureBox1.MouseDown += new MouseEventHandler(


      pictureBox1.MouseUp   += new MouseEventHandler(OnMouseUp);

      pictureBox1.MouseMove += new MouseEventHandler(



   private void OnMouseDown(object sender, MouseEventArgs e)


      lastPoint.X = e.X;

      lastPoint.Y = e.Y;


   private void OnMouseUp(object sender, MouseEventArgs e)


      lastPoint = Point.Empty;


   //Move the form in response to the mouse being dragged

   private void OnMouseMove(object sender, MouseEventArgs e)


      if (lastPoint != Point.Empty) 


         //Move form in response to mouse movement

         int xInc = e.X - lastPoint.X;

         int yInc = e.Y - lastPoint.Y;

         this.Location = new Point(this.Left + xInc, 




   // Close Window

   private void button1_Click(object sender, System.EventArgs e)





The logic is straightforward. When the user clicks the PictureBox, the coordinates are recorded as lastPoint. As the user moves the mouse, the Location property of the form is adjusted to reflect the difference between the new coordinates and the original saved location. When the mouse button is raised, lastPoint is cleared. Note that a complete implementation should also include code to handle form resizing.

Setting Form Location and Size

The initial location of a form is determined directly or indirectly by its StartPosition property. As described in Table 6-6, it takes its value from the FormStartPosition enumeration. These values allow it to be placed in the center of the screen, in the center of a parent form, at a Windows default location, or at an arbitrarily selected location. Manual offers the greatest flexibility because it allows the program to set the location.

Table 6-6. The Life Cycle of a Modeless Form


Events Triggered


Form object created


The form's constructor is called. In Visual Studio, the InitializeComponent method is called to initialize the form.

Form displayed:




The Load event is called first, followed by the Activated event.

Form activated


This occurs when the user selects the form. This becomes an "active" form.

Form deactivated


Form is deactivated when it loses focus.

Form closed




Form is closed by executing Form.Close or clicking on the form's close button.

The initial location is normally set in the Form.Load event handler. This example loads the form 200 pixels to the right of the upper-left corner of the screen:

private void opaque_Load(object sender, System.EventArgs e)


   this.DesktopLocation = new Point(200,0);


The form's initial location can also be set by the form that creates and displays the form object:

opaque opForm = new opaque();

opForm.Opacity = 1;

opForm.TopMost = true;   //Always display form on top

opForm.StartPosition = FormStartPosition.Manual;

opForm.DesktopLocation = new Point(10,10);


This code creates an instance of the form opaque and sets its TopMost property so that the form is always displayed on top of other forms in the same application. The DeskTopLocation property sets the form's initial location. For it to work, however, the StartPostion property must first be set to FormStartPosition.Manual.

Core Note

The DesktopLocation property sets coordinates within a screen's working area, which is the area not occupied by a task bar. The Location property of the Control class sets the coordinates relative to the upper-left edge of the control's container.

A form's size can be set using either its Size or ClientSize property. The latter is usually preferred because it specifies the workable area of the form梩he area that excludes the title bar, scrollbars, and any edges. This property is set to an instance of a Size object:

this.ClientSize = new System.Drawing.Size(208, 133);

It is often desirable to position or size a form relative to the primary (.NET supports multiple screens for an application) screen size. The screen size is available through the Screen.PrimaryScreen.WorkingArea property. This returns a rectangle that represents the size of the screen excluding task bars, docked toolbars, and docked windows. Here is an example that uses the screen size to set a form's width and height:

int w = Screen.PrimaryScreen.WorkingArea.Width;

int h = Screen.PrimaryScreen.WorkingArea.Height;

this.ClientSize = new Size(w/4,h/4);

After a form is active, you may want to control how it can be resized. The aptly named MinimumSize and MaximumSize properties take care of this. In the following example, the maximum form size is set to one-half the width and height of the working screen area:

//w and h are the screen's width and height

this.MaximumSize = new Size(w/2,h/2);

this.MinimumSize = new Size(200, 150);

Setting both width and height to zero removes any size restrictions.

Displaying Forms

After a main form is up and running, it can create instances of new forms and display them in two ways: using the Form.ShowDialog method or the Form.Show method inherited from the Control class. Form.ShowDialog displays a form as a modal dialog box. When activated, this type of form does not relinquish control to other forms in the application until it is closed. Dialog boxes are discussed at the end of this section.

Form.Show displays a modeless form, which means that the form has no relationship with the creating form, and the user is free to select the new or original form. If the creating form is not the main form, it can be closed without affecting the new form; closing the main form automatically closes all forms in an application.

The Life Cycle of a Modeless Form

A form is subject to a finite number of activities during its lifetime: It is created, displayed, loses and gains focus, and finally is closed. Most of these activities are accompanied by one or more events that enable the program to perform necessary tasks associated with the event. Table 6-6 summarizes these actions and events.

Let's look at some of the code associated with these events.

Creating and Displaying a Form

When one form creates another form, there are coding requirements on both sides. The created form must set up code in its constructor to perform initialization and create controls. In addition, delegates should be set up to call event handling routines. If using Visual Studio.NET, any user initialization code should be placed after the call to InitializeComponent.

For the class that creates the new form object, the most obvious task is the creation and display of the object. A less obvious task may be to ensure that only one instance of the class is created because you may not want a new object popping up each time a button on the original form is clicked. One way to manage this is to take advantage of the Closed event that occurs when a created form is closed (another way, using OwnedForms, is discussed shortly). If the form has not been closed, a new instance is not created. The code that follows illustrates this.

An EventHandler delegate is set up to notify a method when the new form, opForm, is closed. A flag controls what action occurs when the button to create or display the form is pushed. If an instance of the form does not exist, it is created and displayed; if it does exist, the Form.Activate method is used to give it focus.

//Next statement is at beginning of form's code

public opaque opForm; 

bool closed = true;   //Flag to indicate if opForm exists

//Create new form or give focus to existing one

private void button1_Click(object sender, System.EventArgs e)


   if (closed)


      closed = false;

      opForm = new opaque();

      //Call OnOpClose when new form closes

      opForm.Closed += new EventHandler(OnOpClose);

      opForm.Show();     //Display new form object

   } else {

      opForm.Activate();  //Give focus to form



//Event handler called when child form is closed

private void OnOpClose(object sender, System.EventArgs e)


   closed = true;   //Flag indicating form is closed


Form Activation and Deactivation

A form becomes active when it is first shown or later, when the user clicks on it or moves to it using an Alt-Tab key to iterate through the task bar. This fires the form's Activated event. Conversely, when the form loses focus梩hrough closing or deselection梩he Deactivate event occurs. In the next code segment, the Deactivate event handler changes the text on a button to Resume and disables the button; the Activated event handler re-enables the button.

this.Deactivate += new System.EventHandler(Form_Deactivate);

this.Activated  += new System.EventHandler(Form_Activate);


void Form_Deactivate(object sender, EventArgs e) 

{   button1.Enabled = false;   

    button1.Text = "Resume";      }

void Form_Activate(object sender, EventArgs e)

{   button1.Enabled = true;   }

Closing a Form

The Closing event occurs as a form is being closed and provides the last opportunity to perform some cleanup duties or prevent the form from closing. This event uses the CancelEventHandler delegate to invoke event handling methods. The delegate defines a CancelEventArgs parameter that contains a Cancel property, which is set to true to cancel the closing. In this example, the user is given a final prompt before the form closes:

this.Closing += new CancelEventHandler(Form_Closing);

void Form_Closing(object sender, CancelEventArgs e)


   if(MessageBox.Show("Are you sure you want to Exit?", "",

      MessageBoxButtons.YesNo) == DialogResult.No)


      //Cancel the closing of the form

      e.Cancel = true;



Forms Interaction桝 Sample Application

When multiple form objects have been created, there must be a way for one form to access the state and contents of controls on another form. It's primarily a matter of setting the proper access modifiers to expose fields and properties on each form. To illustrate, let's build an application that consists of two modeless forms (see Figure 6-8). The main form contains two controls: a Textbox that holds the document being processed and a Search button that, when clicked, passes control to a search form. The search form has a Textbox that accepts text to be searched for in the main form's document. By default, the search phrase is any highlighted text in the document; it can also be entered directly by the user.

Figure 6-8. Text search application using multiple forms

When the Find Next button is pushed, the application searches for the next occurrence of the search string in the main document. If an occurrence is located, it is highlighted. To make it more interesting, the form includes options to search forward or backward and perform a case-sensitive or case-insensitive search.

The main challenge in developing this application is to determine how each form makes the content of its controls available to the other form. DocForm, the main form, must expose the contents of documentText so that the search form can search the text in it and highlight an occurrence of matching text. The search form, SearchForm, must expose the contents of txtSearch, the TextBox containing the search phrase, so that the main form can set it to the value of any highlighted text before passing control to the form.

DocForm shares the contents of documentText through a text box field myText that is assigned the value of documentText when the form loads. Setting myText to public static enables the search form to access the text box properties by simply qualifying them with DocForm.myText.

public static TextBox myText;   //Declare public variable

private void docForm_Load(object sender, System.EventArgs e)


   myText = documentText;


SearchForm exposes the contents of txtSearch to other objects through a write-only string property.

public String SearchPhrase


   set { txtSearch.Text = value;}   //Write Only


DocForm, as well as any object creating an instance of SearchForm, can set this property. Now let's look at the remaining code details of the two forms.

Code for the Main Form

When the button on DocForm is clicked, the application either creates a new instance of SearchForm or passes control to an existing instance. In both cases, it first checks its text box and passes any highlighted text (SelectedText) to the SearchForm object via its SearchPhrase property (see Listing 6-5). Techniques described in earlier examples are used to create the object and set up a delegate to notify the DocForm object when the search form object closes.

Listing 6-5. Method to Pass Control to Search Form Instance

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

   //Create instance of search form if it does not exist

   if (closed) 


      closed= false;

      searchForm = new SearchForm();   //Create instance

      searchForm.TopMost = true;

      searchForm.Closed += new EventHandler(onSearchClosed);

      searchForm.StartPosition = FormStartPosition.Manual;

      searchForm.DesktopLocation = new Point(this.Right-200, 


      searchForm.SearchPhrase = documentText.SelectedText;


   } else {

      searchForm.SearchPhrase = documentText.SelectedText;




private void onSearchClosed(object sender, System.EventArgs e) 

{   closed= true;   }

Code for the Search Form

Listing 6-6 displays the code executed when the Find Next button is clicked. The search for the next occurrence of the search string can proceed up the document using the LastIndexOf method or down the document using IndexOf. Logic is also included to ignore or recognize case sensitivity.

Listing 6-6. Search for Matching Text on Another Form

private void btnFind_Click(object sender, System.EventArgs e) 


   int ib;      //Index to indicate position of match

   string myBuff = DocForm.myText.Text; //Text box contents

   string searchText= this.txtSearch.Text;  //Search string

   int ln = searchText.Length;          //Length of search string

   if (ln>0) 


      //Get current location of selected text

      int selStart = DocForm.myText.SelectionStart;

      if (selStart >= DocForm.myText.Text.Length) 


         ib = 0; 

      } else {

         ib = selStart + ln;


      if (!this.chkCase.Checked) //Case-insensitive search


         searchText = searchText.ToUpper();

         myBuff = myBuff.ToUpper();


      if (this.radDown.Checked)ib = 


      if (this.radUp.Checked && ib>ln-1)ib = 


      if (ib >= 0)        //Highlight text on main form


         DocForm.myText.SelectionStart = ib;

         DocForm.myText.SelectionLength = txtSearch.Text.Length;




Owner and Owned Forms

When a form displays an instance of a modeless form, it does not by default create an explicit relationship between itself and the new form. The forms operate autonomously: They either can be closed (except for a main form, which causes all forms to be closed) or minimized without affecting the other; and the creator form has no easy way to distinguish among instances of the forms it has launched.

Often, however, one form does have a dependency on the other. In the preceding example, the floating search window exists only as a companion to a document that it searches. Its relationship to the form that created it is referred to as an owner-owned relationship. In .NET, this can be more than just a logical relationship. A form has an Owner property that can be set to the instance of the form that "owns" it. After this relationship is formally established, the behavior of the owner and owned form(s) is linked. For example, the owned form is always visually on top of its owner form. This eliminates the need to make SearchForm a TopMost form in our preceding example.

An owner-owned relationship is easily established by setting the Owner property of a newly created form to the form that is creating it.

opaque opForm = new opaque();

opForm.Owner = this;   //Current form now owns new form


This relationship affects the user's interaction with the form in three ways: The owned form is always on top of the owner form even if the owner is active; closing the owner form also closes the owned form; and minimizing the owner form minimizes all owned forms and results in only one icon in the task bar.

Another advantage of the owner-owned relationship is that an owner form has an OwnedForms collection that contains all the owned forms it creates. The following example demonstrates how an owner form creates two owned forms, opForm and opForm2, and then enumerates the collection to set the caption of each form before displaying it:

opaque opForm = new opaque();

opForm.Owner = this;  //Set current form to owner form

opaque opForm2 = new opaque();

opForm2.Owner = this; //Set current form to owner form

for (int ndx=0; ndx<this.OwnedForms.Length; ndx++)


   myForms.Text = "Owner: Form1 - Form"+ndx.ToString();



Note that although modal forms exhibit the features of an owned form, the Owner property must be set to establish an explicit relationship.

Message and Dialog Boxes

.NET provides a set of classes and enumerations that make it easy to create a message or dialog window to interact with a user. The simplest approach is to use the MessageBox class and its versatile Show method. The other approach is to create a custom form and invoke it with the form's ShowDialog method. Both of these methods create modal forms.


The MessageBox class uses its Show method to display a message box that may contain text, buttons, and even an icon. The Show method includes these overloads:


static DialogResult Show(string msg) 

static DialogResult Show(string msg, string caption) 

static DialogResult Show(string msg, string caption, 

      MessageBoxButtons buttons)

static DialogResult Show(string msg, string caption,

      MessageBoxButtons buttons, MessageBoxIcon icon, 

      MessageBoxDefaultButton defBtn)

DialogResult. The method returns one of the enum members Abort, Cancel, Ignore, No, None, OK, Retry, and Yes.

MessageBoxIcon. This enumeration places an icon on the message box. Members include Asterisk, Error, Exclamation, Hand, Information, None, Question, Stop, and Warning.

MessageBoxButtons. This is an enumeration with values that determine which buttons are displayed in the message box. Its members are AbortRetryIgnore, OK, OKCancel, RetryCancel, YesNo, and YesNoCancel. The buttons correspond to the text in the member name. For example, YesNo results in a form with a Yes and No button.

MessageBoxDefaultButton. This an enumeration that defines the default button on the screen. Its members are Button1, Button2, and Button3.

Figure 6-9, which is created with the following statement, provides a visual summary of these parameter options:

MessageBox.Show("OK to Close", "Game Status",  


      MessageBoxDefaultButton.Button2 );

Figure 6-9. MessageBox.Show example

Clicking one of the three buttons returns a value of DialogResult.Yes, DialogResult.No, or DialogResult.Cancel, respectively.


The ShowDialog method permits you to create a custom form that is displayed in modal mode. It is useful when you need a dialog form to display a few custom fields of information. Like the MessageBox, it uses buttons to communicate with the user.

The form used as the dialog box is a standard form containing any controls you want to place on it. Although not required, the form's buttons are usually implemented to return a DialogResult enum value. The following code handles the Click event for the two buttons shown on the form in Figure 6-10:

private void buttonOK_Click(object sender, System.EventArgs e)

{ this.DialogResult = DialogResult.OK; }

private void buttonCancel_Click(object sender, System.EventArgs e)

{ this.DialogResult = DialogResult.Cancel; }

Figure 6-10. Creating a menu with VS.NET

To complete the form, we also need to set a default button and provide a way for the form to be cancelled if the user presses the Esc key. This is done by setting the form's AcceptButton and CancelButton properties in the form's constructor.

AcceptButton = buttonOK;      //Button to receive default focus

CancelButton = buttonCancel;  //Fires when Esc pushed

The code that creates and displays the form is similar to previous examples. The only difference is that the new form instance calls its ShowDialog method and returns a DialogResult type result.

customer cust = new customer();

cust.MinimizeBox = false;

cust.MaximizeBox = false;

if (cust.ShowDialog() == DialogResult.OK) 

{  MessageBox.Show("Returns OK"); }


{  MessageBox.Show("Returns Cancel"); }

Multiple Document Interface Forms

A Multiple Document Interface (MDI) application is characterized by one application window and several document windows. Structurally, a single container is used to hold multiple documents. To manage the collection of documents, the MDI application includes a menu system with options to open, save, and close a document; switch between documents; and arrange the documents in various visual layouts.

No special classes are required to create an MDI application. The only requirement is that one form be designated the container by setting its IsMdiContainer property to true. Child forms are designated by setting their MdiParent property to the container form.

The MDI form in Figure 6-11 shows the three elements that comprise an MDI form: the parent container; the child form(s); and a menu to manage the creation, selection, and arrangement of the child forms.

Figure 6-11. MDI form

The container form is created by including this statement in its constructor:

this.IsMdiContainer = true;

By tradition, child forms are created by selecting an option on the File menu such as File-New or File-Open. The supporting code creates an instance of the child form and sets its MdiParent property.

invForm myForm = new invForm();

myForm.MdiParent = this;

mdiCt += mdiCt;   //Count number of forms created

myForm.Text= "Invoice" + mdiCt.ToString();


A variable that counts the number of forms created is appended to each form's Text property to uniquely identify it.

Creating a Menu and MDI Form

A discussion of MDI forms is incomplete without considering the requirements for a menu to manage the windows within the container. Minimally, an MDI parent menu should contain a File section for creating and retrieving forms and a Windows section that lists all child forms and permits form selection.

A basic menu is constructed from two classes: the MainMenu class that acts as a container for the whole menu structure and the MenuItem class that represents the menu items in the menu. Both of these classes expose a MenuItems collection property that is used to create the menu hierarchy by adding subitems to each class that represent the menu options. After the menu items are in place, the next step is to tie them to appropriate event handling routines using the familiar delegate approach. Let's step through an example that demonstrates how to create the menu system shown in Figure 6-12. Afterwards, we'll look at creating the menu in Visual Studio.NET. It is certainly much quicker and easier to use VS.NET, but it is less flexible if you need to create menus at runtime.

Figure 6-12. MDI Form menu

The first step is to declare the main menu object and the menu items as class variables. (To avoid repetition, code for all menu items is not shown.)

private MainMenu mainMenu1;

private MenuItem menuItem1;   //File

private MenuItem menuItem2;   //Edit

private MenuItem menuItem3;   //Window

private MenuItem menuItem4;   //File - New

The main menu and menu items are created inside the class constructor:

this.mainMenu1 = new System.Windows.Forms.MainMenu();

this.menuItem1 = new System.Windows.Forms.MenuItem("File");

this.menuItem2 = new System.Windows.Forms.MenuItem("Edit");

this.menuItem3 = new System.Windows.Forms.MenuItem("Window");

this.menuItem4 = new System.Windows.Forms.MenuItem("New");

Next, the menu hierarchy is established by adding menu items to the main menu object to create the menu bar. The menu bar items then have menu items added to their MenuItems collection, which creates the drop-down menu.

//Add menu items to main menu object


      System.Windows.Forms.MenuItem[] {




//Add menu item below File   


//Add menu items to Window menu item

this.menuItem3.MdiList = true;    //Causes child forms to display


System.Windows.Forms.MenuItem[] {this.menuItem5,

      this.menuItem6, this.menuItem7, this.menuItem8});

//Set menu on form

this.Menu = this.mainMenu1;

The main points to observe in this code are:

  • The Add and AddRange methods add a single or multiple menu items to the MenuItems collection.

  • Setting a menu item's MdiList property to TRue causes a list of child forms to appear in the menu below that menu item (Invoice1 and Invoice2 are listed in Figure 6-12).

  • To place a menu on a form, set the form's Menu property to the MainMenu object.

The final step is to set up event handling code that provides logic to support the menu operations. Here is the code to define a delegate and method to support an event fired by clicking the File朜ew menu item. The code creates a new instance of invForm each time this menu item is clicked.

//Following is defined in constructor

MenuItem4.Click += new System.EventHandler(menuItem4_Click);

private void menuItem4_Click(object sender, System.EventArgs e)


   invForm myForm = new invForm();

   myForm.MdiParent = this;

   mdiCt += mdiCt;   //Count number of forms created

   myForm.Text= "Invoice" + mdiCt.ToString();



The Window option on the menu bar has submenu items that let you rearrange the child forms within the MDI container. The LayoutMdi method of a form makes implementing this almost trivial. After setting up delegates in the usual manner, create the event handling routines:

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



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



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



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



The methods reorder the window by passing the appropriate MdiLayout enumeration value to the LayoutMdi method.

Creating an MDI Menu Using VisualStudio.NET

With the Form Designer open, double click the MainMenu icon in the Toolbox window. Two things happen: An icon appears in the component tray at the bottom and a menu template appears docked to the top of the form. Type the menu item titles into the cells that appear (see Figure 6-13). The top horizontal row of cells represents the menu bar; by moving vertically, you create drop-down menu items below the top-level items. After typing in the item name, double click the cell to create a Click event for the menu item. VS.NET creates the delegate and method stub automatically.

Figure 6-13. Creating a menu with VS.NET

Use the Property Window (press F4), which displays properties of the active cell, to change the default names assigned to menu items and set any other values.

    Previous Section  < Day Day Up >  Next Section