Visual Basic 2005 for Programmers (2nd Edition)
14.12. Multiple Document Interface (MDI) Windows
In previous chapters, we have built only single document interface (SDI) applications. Such programs (including Microsoft's Notepad and Paint) can support only one open window or document at a time. SDI applications usually have limited abilitiesPaint and Notepad, for example, have limited image- and text-editing features. To edit multiple documents, the user must execute another instance of the SDI application. Most recent applications have multiple document interfaces (MDIs), which allow users to edit multiple documents at oncefor example, graphics applications like Jasc PaintShop Pro and Adobe Photoshop allow you to edit multiple images at once. MDI programs also tend to be more complexPaintShop Pro and Photoshop have a greater number of image-editing features than does Paint. The main application window of an MDI program is called the parent window, and each window inside the application is referred to as a child window. Although an MDI application can have many child windows, there is only one parent window. Furthermore, a maximum of one child window can be active at once. Child windows cannot be parents themselves and cannot be moved outside their parent. In all other ways (closing, minimizing, resizing, etc.), a child window behaves like any other window. A child window's functionality can be different from the functionality of other child windows of the parent. For example, one child window might allow the user to edit images, another might allow the user to edit text and a third might display network traffic graphically, but all could belong to the same MDI parent. Figure 14.37 depicts a sample MDI application. Figure 14.37. MDI parent window and MDI child windows.
To create an MDI Form, create a new Form and set its IsMdiContainer property to true. The Form changes appearance, as in Fig. 14.38. Figure 14.38. SDI and MDI forms.
Next, create a child Form class to be added to the Form. To do this, right click the project in the Solution Explorer, select Add > Windows Form... and name the file. Edit the Form as you like. To add the child Form to the parent, we must create a new child Form object, set its MdiParent property to the parent Form and call the child Form's Show method. In general, to add a child Form to a parent, you would write Dim childForm As New ChildFormClass() childForm.MdiParent = parentForm childForm.Show() In most cases, the parent Form creates the child, so the parentForm reference is Me. The code to create a child usually resides in an event handler, which creates a new window in response to a user action. Menu selections (such as File > New > Window) are commonly used to create new child windows. Class Form property MdiChildren returns an array of child Form references. This is useful if the parent window wants to check the status of all its children (for example, ensuring that all are saved before the parent closes). Property ActiveMdiChild returns a reference to the active child window; it returns Nothing if there are no active child windows. Other features of MDI windows are described in Fig. 14.39.
Child windows can be minimized, maximized and closed independently of each other and the parent window. Figure 14.40 shows two imagesone containing two minimized child windows and a second containing a maximized child window. When the parent is minimized or closed, the child windows are minimized or closed as well. Note that the title bar in Fig. 14.40(b) is Form1 - [Child2]. When a child window is maximized, its title bar text is inserted into the parent window's title bar. When a child window is minimized or maximized, its title bar displays a restore icon, which can be used to return the child window to its previous size (i.e., its size before it was minimized or maximized). Figure 14.40. Minimized and maximized child windows.
Visual Basic provides a property that helps track which child windows are open in an MDI container. Property MdiWindowListItem of class MenuStrip specifies which menu, if any, displays a list of open child windows. When a new child window is opened, an entry is added to the list (as in the first screen of Figure 14.41). If nine or more child windows are open, the list includes the option More Windows..., which allows the user to select a window from a list in a dialog. Figure 14.41. MenuStrip property MdiWindowListItem example.
Good Programming Practice 14.1
MDI containers allow you to organize child windows by calling method LayoutMdi of the parent Form. Method LayoutMdi receives as its argument one of the MdiLayout enumeration constantsArrangeIcons, Cascade, TileHorizontal and TileVertical. Tiled windows completely fill the parent and do not overlap; such windows can be arranged horizontally (value TileHorizontal) or vertically (value TileVertical). Cascaded windows (value Cascade) overlapeach is the same size and displays a visible title bar, if possible. Value ArrangeIcons arranges the icons for any minimized child windows. If minimized windows are scattered around the parent window, value ArrangeIcons orders them neatly at the bottom-left corner of the parent window. Figure 14.42 illustrates the values of the MdiLayout enumeration. Figure 14.42. MdiLayout enumeration values.
(a) ArrangeIcons
(b) Cascade
(c) TileHorizontal
(d) TileVertical
Class FrmUsingMDI (Fig. 14.43) demonstrates MDI windows. Class FrmUsingMDI uses three instances of child FrmChild (Fig. 14.44), each containing a PictureBox that displays an image. The parent MDI Form contains menus that enable users to create and arrange child Forms. Figure 14.43. MDI parent-window class.
Figure 14.44. MDI child FrmChild.
FrmUsingMDI
Figure 14.43 presents class FrmUsingMDIthe application's MDI parent Form. This Form, which is created first, contains two top-level menus. The first of these menus, File (fileToolStripMenuItem), contains both an Exit item (exitToolStripMenuItem) and a New submenu (newToolStripMenuItem) consisting of items for each child window. The second menu, Window (windowToolStripMenuItem), provides options for laying out the MDI children, plus a list of the active MDI children. In the Properties window, we set the Form's IsMdiContainer property to TRue, making the Form an MDI parent. In addition, we set the MenuStrip's MdiWindowListItem property to windowToolStripMenuItem so that the Window menu can list the open MDI child windows. The Cascade menu item's (cascadeToolStripMenuItem) event handler (lines 4348) cascades the child windows by calling the parent Form's LayoutMdi method with the argument MdiLayout.Cascade (line 47). The Tile Horizontal menu item's (tileHorizontalToolStripMenuItem) event handler (lines 5156) arranges the child windows horizontally by calling the parent Form's LayoutMdi method with the argument MdiLayout.TileHorizontal (line 55). Finally, the Tile Vertical menu item's (tileVerticalToolStripMenuItem) event handler (lines 5964) arranges the child windows vertically by calling the parent Form's LayoutMdi method with the argument MdiLayout.TileVertical (line 63). FrmChild
At this point, the application is still incompletewe must define the MDI child class. To do this, right click the project in the Solution Explorer and select Add > Windows Form.... Then name the new class in the dialog as FrmChild (Fig. 14.44). Next, add a PictureBox (picDisplay) to FrmChild. In the constructor, line 8 sets the title bar text. Lines 1112 set picDisplay's Image property to an Image by using method FromFile (a Shared method of class Image). The parent MDI Form (Fig. 14.43) creates new child windows using class FrmChild. The event handlers in lines 532 create a new child Form corresponding to the menu item clicked. Lines 9, 19 and 29 create new instances of FrmChild. Lines 10, 20 and 30 set each child's MdiParent property to the parent Form (Me). Lines 11, 21 and 31 call method Show to display each child Form. |