Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
(ebook) Visual Studio .NET Mastering Visual Basic.pdf
Скачиваний:
136
Добавлен:
17.08.2013
Размер:
15.38 Mб
Скачать

MDI APPLICATIONS: THE BASICS 839

of the same type and use a common menu structure that applies to all open documents. In the following sections, we are going to discuss the basic behavior of MDI applications, their differences from regular Single Document Interface (SDI) applications, and how to build MDI applications.

MDI Applications: The Basics

MDI applications must have at least two forms, the parent form and one or more child forms. There may be many child forms contained within the parent form, but there can be only one parent form. The parent form is the MDI form, or MDI container, because it contains all child forms.

The parent form may not contain any controls. While the parent form is open in design mode, the icons on the Toolbox aren’t disabled, but you can’t place any controls on the form. The parent form can, and usually does, have its own menu. While one or more child forms are displayed, the menu of the child forms takes over and it’s displayed on the MDI form’s menu bar. This is not a requirement, of course, and you can manipulate the parent form’s menu with the techniques we discussed in Chapter 4. In this chapter, you’ll learn about a feature that is specific to the menus of MDI applications, namely how to merge two different menus—the menu of the MDI form and the menu of the child forms.

In the following section, we’re going to build a simple MDI application. In the process, we’ll discuss the steps that are unique to an MDI application.

Building an MDI Application

Building an MDI application is a fairly straightforward process, but quite a few steps are unique to MDI applications. In this section, we’re going to build a typical MDI application that demonstrates all the built-in features of the MDI. In a later section, we’re going to add more functionality to this application. As you will see, once you get the interface right and you have the skeleton of a working MDI application, adding specific functionality to it is as simple as adding functionality to an SDI application. In effect, all the code belongs to the child form, and the MDI form is simply a container with a few lines of supporting code.

The application we’ll build in this section is the skeleton of an MDI text-editing application, and it’s shown in Figure 19.3. All child forms of the application are the same, and they determine the functionality of the application. The commands of the menu are placeholders, with no code behind them—we’ll add the code later. For now, we’re going to focus on the mechanics of designing MDIs.

Before building the application, let’s go over the basic characteristics of an MDI application. When you start an MDI application, you see the container form. Most applications automatically display a new document of the type they can handle. Excel, for instance, opens a new XLS file when you start it. Closing this document disables most of the commands in Excel’s menus. Without an active document, these commands are meaningless. They’re activated automatically again as soon as a new document is opened on a child form. The child forms usually have more menu commands, which are merged with the initial menu of the MDI form’s menu commands.

The child forms don’t display their own menus. When you design a child form, you add a menu as usual, but this menu will appear on the menu bar of the MDI form—it will either replace the initial menu of the MDI form or it will be merged with it. You may have also noticed that the menu of an MDI application changes according to the state of the document on the active child form. If you

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

840 Chapter 19 THE MULTIPLE DOCUMENT INTERFACE

select some text in the active document, the Cut and Copy commands will be enabled. If you switch to another child form whose document contains no selection, these two commands will be disabled. In effect, each child form has its own menu, and each time you switch to another child form, its menu becomes the application’s menu. You can design an MDI application that uses child forms with totally different menus, but this is quite unusual—at the very least, it will confuse the users.

Figure 19.3

MDIPad is an MDI text-editing application.

Let’s now build the application. Start a new project and name it MDIProject. Select the project’s form in the Solution window, and rename it from Form1.vb to MDIForm.vb. This form will become the window that will host the child forms at runtime. To specify this function of the form, select the MDIForm component in Solution Explorer, and in the Properties window locate the IsMdiContainer property. This property determines whether the form will act as an MDI parent form (in other words, whether it will be a container for child forms). The default value is False, and you must change it to True. While you’re setting the form’s properties, change the MDI form’s caption to “MDIForm”.

We’ve taken care of the parent form. We must now create a child form. Because all child forms are usually the same, we’ll create a single form that will serve as a template for all child windows. It is possible for an MDI application to host child forms that are not identical, but this is rather unusual. In this chapter, we’ll explore MDI applications with child forms that are identical.

Right-click the project’s name in the Solution Explorer window, and from the context menu select Add Add Item. In the dialog box that appears, select Windows Form. Change its name to ChildForm, and click Open to add it to the project. Child forms are regular forms, and you need not set any properties to make them appear in their container. If you run the project now, you will see the parent form and nothing more.

To display a child window at runtime, you must insert a few lines of code. Since the user is in charge of creating and closing child forms, we must add a menu, usually a File menu, that contains a

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

MDI APPLICATIONS: THE BASICS 841

New command. Before we can open a child form, we’ll build a simple menu with a command that allows you to create a new instance of the child form and display it on the parent form.

With the MDI form in the Design window, drop a MainMenu control onto the project. Then create a menu with the structure shown in Table 19.1.

Table 19.1: The Captions and Names of the File and Window Menus

Caption

Name

File

FileMenu

New

FileNew

Exit

FileExit

Window

WindowMenu

Tile Horizontally

WindowTileH

Tile Vertically

WindowTileV

Cascade

WindowCascade

Arrange Icons

WindowArrange

 

 

The first column contains the top-level items, which are the usual File and Window menus. The Window menu is a characteristic of all MDI applications, and we’ll come back to this topic shortly. The File menu contains the two commands you really need when no child form is displayed. The New command instantiates a child form, and the Exit command terminates the application.

Enter the lines in Listing 19.1 in the New menu item’s Click event handler.

Listing 19.1: Instantiating a New Child Form

Private Sub FileNew_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles FileNew.Click Static nWindow As Integer

Dim child As New ChildForm() child.MdiParent = Me

child.Text = “Child window # “ & nWindow.ToString child.Show()

nWindow = nWindow + 1 End Sub

Creating and displaying an instance of the child form isn’t new to you; this is the same code we used in Chapter 4 to display a form or dialog box from within another form. We create a variable that represents the form and then we call its Show method. In our example, we also set the caption of the form. The nWindow variable is static so that it’s increased every time a child control is added.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

842 Chapter 19 THE MULTIPLE DOCUMENT INTERFACE

This variable is used to display a different caption for each child form. Note that the nWindow variable’s value isn’t decreased when a child form is closed. Therefore, there will be gaps in the numbering of the child forms as you close and open new documents, but they will all have a different caption. In a real application, each child form’s caption will be the title of the document displayed.

The line that’s new to you is the following:

Child.MdiParent = Me

which makes the form a child of the MDI form. The child form will appear in its parent’s window, and its menu will be automatically merged with the parent form’s menu. So far, we haven’t designed a menu for the child form, but we’ll do so shortly. You’ll see how the two menus are merged—you can actually specify how the two menus will be merged.

If you run the project now, you’ll be able to open new child forms—each one with a unique cap- tion—resize them in the MDI form’s window, move them around, and close them when you no longer need them. The Window menu’s items aren’t doing anything because we haven’t programmed them yet. You have built a working skeleton of an MDI application, and you’re ready to add some real functionality to your project.

The child form may contain any number of controls since this is the form the user will be interacting with. You can place a multiline TextBox control on the form to experiment with the child forms of the application. Place a button or two on the child form as well, so that you can enter a few lines of code behind them as you go through the example.

Note All MDI child forms are sizable, have borders, and have the usual Control-menu, Close, and Minimize/Maximize buttons, regardless of the settings of the equivalent properties.

The Window Menu

All MDI applications in the Windows environment have a menu called Window that contains two groups of commands. The first group of commands positions the child windows on the MDI form, and the second group consists of the captions of the open child windows (see Figure 19.4). With the commands on this menu, you can change the arrangement of the open windows (or the icons of the minimized windows) and activate any child window.

Figure 19.4

A Window menu of an MDI application

Stop the project and right-click the Window menu item on the MDI form. On the context menu, select Properties. In the Properties window, locate the MDIList property. This property causes the menu to keep track of all open child forms and display their names at the bottom of the Window submenu. This is a characteristic function of the Window menu, and it’s implemented by setting a single property.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

MDI APPLICATIONS: THE BASICS 843

The other four options of the Window menu, which automatically rearrange the child forms within the parent form’s window, are implemented with a call to the LayoutMdi method of the child form. Windows offers three ways of arranging the windows on an MDI form. You can cascade them, tile them vertically, or tile them horizontally. Of course, the user can resize and move the windows around, but the automatic placement comes in handy when the MDI form becomes messy and the user can no longer easily locate the desired window. The placement of the child windows on the form is controlled with the LayoutMdi method, which accepts as argument one of the members of the MdiLayout enu-

meration: TileHorizontal, TileVertical, Cascade, or ArrangeIcons. If you’re not familiar with the

Window menu, check out the application, or open several documents with your favorite MDI application (Excel being one of them) and then rearrange them on the MDI form in all possible ways. By tiling the child forms vertically or horizontally, you can easily compare documents.

Enter the statements shown in Listing 19.2 into each of the four commands of the Window menu.

Listing 19.2: The Window Menu’s Commands

Private Sub WindowTileH_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles WindowTileH.Click Me.LayoutMdi(MdiLayout.TileHorizontal)

End Sub

Private Sub WindowTileV_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles WindowTileV.Click Me.LayoutMdi(MdiLayout.TileVertical)

End Sub

Private Sub WindowCascade_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles WindowCascade.Click Me.LayoutMdi(MdiLayout.Cascade)

End Sub

Private Sub WindowArrange_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles WindowArrange.Click Me.LayoutMdi(MdiLayout.ArrangeIcons)

End Sub

The LayoutMdi method of the parent form automatically rearranges the child forms; all you have to do is supply the proper argument. Run the project again, open a few child forms, and see their names in the Window menu. You can switch to any child form by selecting its name in this menu. The active form’s name is checked automatically in the Window menu. Check out the commands that arrange the child forms as well. The Arrange Icons command applies to forms that are minimized and has no effect on the other forms.

Merging MDI and Child Menus

We now have a working MDI application, but it doesn’t do anything useful yet. We must add a few controls and a menu to the child form in order to build a real application. The parent form has no controls, just a few menu commands to create and close new child forms. In this section, we’re going to add a menu to the child form and merge it with the MDI form’s menu.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

844 Chapter 19 THE MULTIPLE DOCUMENT INTERFACE

Open the child form in the Design window and drop a MainMenu control on it. Then design the menu shown in Table 19.2 (the dashes indicate separators).

Table 19.2: The Captions and Names of the File, Edit, and Format Menus

Caption

Name

File

FileMenu

-

 

Open

FileOpen

Save

FileSave

Save As

FileSaveAs

Close

FileClose

-

 

Preview

FilePreview

Print

FilePrint

Edit

EditMenu

Copy

EditCopy

Cut

EditCut

Paste

EditPaste

-

 

Find

EditFind

Word Wrap

EditWordWrap

Format

FormatMenu

Font

FormatFont

Text Color

TextColor

Page Color

PageColor

 

 

This is the menu of the MDIPad application, which we’ll build in the next few sections. MDIPad is a text editor similar to the TextPad of Chapter 6, but it can maintain many open documents at once with an MDI interface.

As you can see, some of the commands are missing, and they are the ones we’ve already added to the MDI form’s menu. The MDI form has a File menu with the New and Exit commands. These two commands are missing from the child form’s menu. We’re going to merge the two menus and specify that the New command will be the first command in the File menu, while the Exit command will be the last command in the same menu. This also explains why the child form’s File menu starts

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

MDI APPLICATIONS: THE BASICS 845

and ends with a separator. The top separator will be placed under the New command, while the last separator will end up just above the Exit command. The separators aren’t placed automatically when the menus are merged; you must insert them in the child form’s menu. You can also insert them in the MDI form’s menu, but they will appear even when they don’t separate sections of the menu, as they’re supposed to do.

The MDI form’s menu is really minimal because the MDI form is simply a container for the child forms. You can’t do anything without first opening a new document. The child form’s menu contains all the commands users need to interact with the document and edit it. The child form contains all the code of the application, and its menu structure indicates the capabilities of the application.

Note Some applications display the full menu even when no child form is open. These menus usually lead to disabled commands, as there’s no document for the commands to act upon. It’s possible to design an MDI form with the complete menu of the application, but this will complicate your code.

If you run the application at this point and open a new child form with the New command, you will see that the child form’s menu options are added to its parent’s menu. There are two File menus, the first one with two commands (New and Exit) and the second one with the commands of the child form’s File menu. The two menus were merged, but not exactly as we would like them. We must set a few properties to specify how the menus are merged. By default, Form Designer displays the commands of the MDI form followed by the commands of the child form.

Notice that the menus are actually added, not merged. The first commands are those of the MDI form, followed by the commands of the child form. Moreover, menus are combined according to their order in their respective forms, not their names—that’s why you see two File menus. To properly merge two menus, you must set their MergeType and MergeOrder properties.

The MergeType property determines how the items of two menus are merged. Its value can be one of the members of the MenuMerge enumeration. The MenuMerge enumeration’s members are listed in Table 19.3.

Table 19.3: The MenuMerge Enumeration

Member

Description

Add

The menu item of the child form is added to the menu items of the parent MDI form. This is

 

the default setting of the MenuMerge property.

MergeItems

All items of a submenu on the child form are merged with the items of the submenu of the par-

 

ent MDI form. This setting applies to menu items that lead to submenus. The items are

 

merged according to their positions in the respective menus, not by their captions.

Remove

The menu item is ignored when the two menus are merged

Replace

The menu item replaces another item at the same position in the merged menu.

 

 

The Replace option allows you to design the complete menu on the child form and have it replace the MDI form’s menu as soon as the first child form is opened. This, however, means that you must duplicate the menus of the MDI form on the child form.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com