DESIGNING APPLICATION
Working with MDI Applications and Creating Menus
Summary:
Introduces you to the concept of Multiple Document Interface (MDI) and how to
create menus within an MDI application. (20 printed pages)
Objectives
- Learn
to create MDI parent forms
- Learn
to create MDI child forms
- Learn
to create and use menus
Assumptions
The following should be true for you to get
the most out of this document:
- You
are familiar with Microsoft® Visual Studio® .NET
- You
are familiar with designing forms and other user interfaces
Contents
MDI Overview
Create an MDI Project
Creating Menus
Working with MDI Child Forms
Creating Shortcut Menus
Manipulating Menus at Run Time
How Did the Code Work?
Summary
Create an MDI Project
Creating Menus
Working with MDI Child Forms
Creating Shortcut Menus
Manipulating Menus at Run Time
How Did the Code Work?
Summary
This document introduces you to the concept
of Multiple Document Interface (MDI) and how to create menus within an MDI
application. You will learn to create an MDI application in Microsoft Visual
Studio .NET and learn why you might want to use this type of interface. You
will learn about child forms that are contained within the MDI application, and
learn to create shortcut, or context-sensitive, menus.
MDI is a popular interface because it allows
you to have multiple documents (or forms) open in one application. Examples of
MDI applications include Microsoft Word, Microsoft Excel, Microsoft
PowerPoint®, and even the Visual Studio integrated development environment
itself. Each application consists of one (or more) parent windows, each
containing an MDI client area—the area where the child forms (or documents)
will be displayed. Code you write displays as many instances of each of the
child forms that you want displayed, and each child form can only be displayed
within the confines of the parent window—this means you can't drag the child
forms outside the MDI container. Figure 1 shows a basic MDI application in use.
Figure 1. Use MDI to open multiple windows
and have them all contained within the parent area
Single Document Interface
Don't be misled: MDI is only one of several
possible paradigms for creating a user interface. You can also create
applications that display just a single form. They're easier to create, in
fact. Those applications are called Single Document Interface (SDI)
applications. Microsoft Windows® Notepad is an SDI application, and you can
only open a single document at a time. (If you want multiple documents open,
you simply run Notepad multiple times.) You are under no obligation to create
your applications using the MDI paradigm. Even if you have multiple forms in
your project, you can simply have each one as a stand-alone form, not contained
by any parent form.
Uses of MDI
You'll use MDI most often in applications
where the user might like to have multiple forms or documents open
concurrently. Word processing applications (like Microsoft Word), spreadsheet
applications (like Microsoft Excel), and project manager applications (like
Microsoft Project) are all good candidates for MDI applications. MDI is also
handy when you have a large application, and you want to provide a simple
mechanism for closing all the child forms when the user exits the application.
Creating an MDI Parent Form
To create an MDI parent form, you can simply
take one of your existing forms and set its IsMDIContainer property to True.
This form will now be able to contain other forms as child forms. You may have
one or many container forms within your application.
Tip Note
the difference here between Visual Studio .NET and Microsoft Visual Basic® 6.0
behavior. In Visual Basic 6.0, you could only have a single MDI parent form per
application, and you had to use the Project menu to add that one special
form. In Visual Studio .NET, you can turn any form into an MDI parent form by
simply modifying a property, and you can have as many MDI parent forms as you
require within the same project.
You may have as many different child forms
(the forms that remain contained within the parent form) as you want in your
project. A child form is nothing more than a regular form for which you
dynamically set the MdiParent property to refer to the MDI container
form.
Note The
user interface objects you've designed within the Visual Studio environment are
really templates for forms. That is, they don't actually become real
Form objects until you instantiate them at run time. Therefore, your project
can contain as many different templates for MDI child forms as you like. You
can instantiate and then show as many instances of as many different templates
as you need, while your applications are running.
Run-time Features of MDI
Child Forms
At run time, the MDI parent form and the MDI
child forms take on special features:
- All
child forms are displayed within the MDI parent's client area. The
client area is the area below the MDI parent's title bar, any menus, and
any tool bars.
- Child
forms can be moved and sized only within the MDI parent's client area.
- Child
forms can be minimized and their icon will be displayed within the
parent's client area.
- Child
forms can be maximized within the parent's client area and the caption of
the child form is appended to the caption of the MDI form.
- Windows
automatically gives child forms that have their FormBorderStyle
property set to a sizable border a default size. This size is based on the
size of the MDI parent's client area. You can override this by setting the
FormBorderStyle property of the child form to any of the fixed type
of borders.
- Child
forms cannot be displayed modally.
- The
MDI form can be minimized and only one icon will be displayed on the
desktop representing the MDI form and all of its children.
- If
the MDI form is unloaded, all of the loaded children will also be
unloaded.
Note The
client area includes any usable area on the MDI form minus any toolbars or
status bars that you may have added to the MDI form.
In this section, you will walk through the
steps of creating a simple MDI application using Visual Studio .NET. To do
this, you will create a new form that will be the MDI parent form. You will add
some menus to this new form, and then you will load the product form from a
menu as a child form.
Create the MDI Parent Form
To create the MDI parent form
1.
Open Visual Studio .NET
2.
Create a new Windows
application project.
3.
Set the name of the project
to MDI.sln.
4.
Rename the form that is
created automatically to frmMain.vb.
5.
With the frmMain selected,
set the form's IsMdiContainer property to True.
6.
Set the WindowState property
to Maximized.
That's all there is to it: you've created an
MDI parent form.
Your main form will require menus so that you
can perform actions such as opening child forms, copying and pasting data, and
arranging windows. Visual Studio .NET includes a new menu designer that makes
creating and modifying menus a snap.
To add menus to your MDI parent form
1.
Double-click the MainMenu
tool in the Toolbox window to add a new object named MainMenu1 to the form
tray.
Note
Unlike the form designer in Visual Basic 6.0,
the Visual Studio .NET form designer places controls that don't have a user
interface at run time into a special area on the form designer: the form
"tray". They're out of the way, and don't get buried underneath other
controls. This is a real improvement!
2.
At the top of the MDI
parent form, click the box with Type Here in it and type &File.
Tip
Just as in Visual Basic 6.0, inserting an
ampersand (&) into a menu caption displays the caption with an underscore
under the following letter. Pressing Alt+<the letter> acts as a
hotkey, activating the menu item. One thing to note: if you're using Windows
2000 or later, it's possible that the hotkeys won't show up underlined until
you press the Alt key. This setting is buried in the Display applet
within Control Panel. In the Display Properties dialog box, check the
Effects page: the Hide keyboard navigation indicators until I use the Alt
key option controls this behavior.
3.
Press Enter to move
to the next menu item and type &Products.
4.
Press Enter to move
to the next menu item and type a hyphen (-).
Tip
Rather than using the "-" to indicate
a divider in the menu, you can insert the next menu item (Exit, in this case),
and then right-click the new item. Select "Insert Separator" from the
context menu, and Visual Studio .NET will insert a separator above the current
item for you.
5.
Press Enter and type
E&xit.
You have now created the first drop-down menu
on your main form. You should have something that looks like Figure 2.
Figure 2. The menu designer allows you to
type your menu structure in a WYSIWYG fashion
To the right of the File menu and at
the same level, you'll see another small box with the text, Type Here.
Click it and type the following menu items by pressing Enter after each
one.
- &Edit
- Cu&t
- &Copy
- &Paste
Once more to the right of the Edit menu and
at the same level, add the following menu items in the same manner.
- &Window
- &Cascade
- Tile
&Horizontal
- Tile
&Vertical
- &Arrange
Icons
Creating Names for Each
Menu
After creating all the menu items, you'll
need to set the Name property for each. (Because you'll refer to the
name of each menu item from any code you write concerning that menu item, it's
important to choose a name you can understand from within your code.) Instead
of clicking each menu item one at a time and then moving over to the Properties
window to set the Name property, Visual Studio provides a shortcut:
Right-click an item in the menu, then select Edit Names from the context
menu. Now you can simply click each menu item and set the name property
directly on each menu. This is certainly quicker than using the Properties
window to accomplish the same task.
Use the following names for your menu items:
- mnuFile
- mnuFProducts
- mnuFExit
- mnuEdit
- mnuECut
- mnuECopy
- mnuEPaste
- mnuWindow
- mnuWCasade
- mnuWHorizontal
- mnuWVertical
- mnuWArrange
Test out your application: Press F5
and you should see your main MDI window appear with your menu system in place.
Display a Child Form
To add the code that displays the child form,
frmProducts, make sure the main form is open in Design view, and on the File
menu, double-click Products. Visual Studio .NET will create the stub of
the menu item's Click event handler for you. Modify the procedure so that it
looks like the following:
Private
Sub mnuFProducts_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles
mnuFProducts.Click
Dim frm As New frmProducts()
frm.MdiParent = Me
frm.Show()
End
Sub
This code declares a variable, frm, which
refers to a new instance of the frmProducts form in the sample project. Then,
you set the MdiParent property of the new form, indicating that its
parent should be the current form (using the Me keyword). Finally, the
code calls the Show method of the child form, making it appear on the
screen.
Some interesting things to note:
- Me is a built-in keyword in Visual Basic .NET—just as in
Visual Basic 6.0, this keyword refers to the class whose code is currently
running. In this case, that's the MDI parent form, whose menu item you
just clicked.
- You
don't have to set the MdiParent property of the new child form. If
you don't, the form will simply load as a new normal form, outside the MDI
parent. As a matter of fact, you can set the MDI parent to be a different
MDI container if you like.
- If
you don't call the Show method, the child form won't ever display.
Differentiating Between
Child Windows
You'll note that each instance of the
Products form looks identical. You'll most likely need some way to
differentiate the windows. One alternative is to modify the caption of the
window as you load each instance. In the sample, you can create a static
variable to contain a counter, increment that variable each time you open a
form, and then assign that value into the Text property of the form.
To uniquely identify each child form
1.
Modify the
mnuFProducts_Click procedure so that it looks like this:
Private
Sub mnuFProducts_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuFProducts.Click
Dim frm As frmProducts
Static intCount As Integer
frm = New frmProducts()
' Increment the caption counter.
intCount += 1
' Set the caption to be unique.
frm.Text = frm.Text & " "
& intCount.ToString()
frm.MdiParent = Me
frm.Show()
End
Sub
2.
Run the project, create a
few Products forms, and note that the caption of each form includes a different
number.
Note
What's that Static keyword?
Using Static, rather than Dim, to declare a variable inside a
procedure creates a variable that maintains its value from one invocation of the
procedure to the next. When you declare a variable using Dim, that
variable gets reinitialized each time the procedure is called. When you use Static,
the variable maintains its value. That's what you want, in this case—you want
intCount to maintain its value, so that it continues to increment each time you
create a new instance of frmProducts.
Child Menus in MDI
Applications
What if a child form has its own set of
menus? How do those menus interact with the menus of the parent form? In
previous versions of Visual Basic you really didn't have much control over the
behavior—the menus of the currently active child simply replaced the menus of
its parent. In Visual Studio .NET, however, you can control how the menus
interact, using the MergeOrder and MergeType properties of the
individual menu items.
The MergeOrder property controls
the relative position of the menu item when its menu structure gets merged with
the parent form's menus. The default value for this property is 0, indicating
that this menu item will be added at the end of the existing menu items. The MergeType
property controls how the menu item behaves when it has the same merge
order as another menu item being merged. Table 1 shows a list of the possible
values you can assign to the MergeType property.
Table 1. The MergeType property allows you to
specify what happens when menu items merge
|
Value
|
Description
|
|
Add
|
The
MenuItem is added to the collection of existing MenuItem objects in a merged
menu. (Default)
|
|
MergeItems
|
All
submenu items of this MenuItem are merged with those of existing MenuItem
objects at the same position in a merged menu.
|
|
Remove
|
The
MenuItem is not included in a merged menu.
|
|
Replace
|
The
MenuItem replaces an existing MenuItem at the same position in a merged menu.
|
By default, a menu item's MergeOrder
property is set to 0. The MergeType property is set to Add by
default. This means that if you create a child form with a menu on it, the menu
will be added at the end of the main menu. Consider Figure 3, which shows a
child form called from the parent form's main menu. This form has a Maintenance
menu on it (and the parent form does not). All of the items on the parent's
main menu have their MergeOrder properties set to 0 and this menu's MergeOrder
property is set to 0, so this menu will be added at the end of the main menu on
the MDI parent form.
Figure 3. A child form that has menus will by
default be added to the end of the main menu
To create the form in Figure 3
1.
On the Project menu,
click Add Windows Form.
2.
Set the new form's name to
frmChildWithMenus.vb.
3.
Add a MainMenu control to
this form.
4.
Set the Name property for
the MainMenu control to mnuMainMaint.
5.
Add the following menus as
shown in Table 2.
Table
2. Windows Form menus
|
Menu
|
Name
|
|
&Maintenance
|
mnuMaint
|
|
&Suppliers
|
mnuMSuppliers
|
|
&Categories
|
mnuMCategories
|
If you were to call this form exactly like
you did the Products form in the previous section you will see that your main
form looks like Figure 4. You can see that by default, the menu is added to the
end of this form.
Figure 4. Menus are added to the end of the
main menu by default
Call this form by adding a new menu item
under the File menu:
1.
Open frmMain.vb in Design
view.
2.
Click on the separator
after the Products menu item and press the Insert key to add a
new menu item.
3.
Type Child form with
Menus as the text of this new menu item.
4.
Set the Name property of
this new menu item to mnuFChild.
5.
Double click this new menu
item and modify its Click event handler so that it looks like this:
Private
Sub mnuFChildMenus_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuFChildMenus.Click
Dim frm As New frmChildWithMenus()
frm.MdiParent = Me
frm.Show()
End
Sub
Note
If you wish to merge the Maintenance
menu in between the Edit and Window menus, you could set the MergeOrder
property on the Edit menu item to 1, and the MergeOrder property
on the Window menu to a 2. Then on the Maintenance menu item on
frmChildWithMenus, set the MergeOrder property to 1 and leave the MergeType
with its default value, Add. Taking these steps will add the Maintenance
menu after the menu on the main form with the same MergeOrder number as
it has (that is, after the Edit menu, but before the Window
menu).
If you have multiple child forms open, you
may want to have them arrange themselves, much as you can do in Word or Excel,
choosing options under the Window menu. Table 3 lists the available
options when arranging child windows.
Table 3. Choose one of these values when
arranging child windows
|
Menu Item
|
Enumerated Value
|
|
Tile
Horizontal
|
MdlLayout.TileHorizontal
|
|
Tile
Vertical
|
MdiLayout.TileVertical
|
|
Cascade
|
MdiLayout.Cascade
|
|
Arrange
Icons
|
MdiLayout.ArrangeIcons
|
Add some menus to your main form for each of these
options:
1.
Open frmMain.vb in
Design view.
2.
On the Window menu, double-click
Cascade.
3.
For the Cascade menu item,
modify the Click event handler so that it looks like the following:
Private
Sub mnuWCascade_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuWCascade.Click
Me.LayoutMdi(MdiLayout.Cascade)
End
Sub
On
the Window menu, double-click each menu item and add the appropriate
code.
Tip
The LayoutMDI method replaces the Arrange
method you may have used in Visual Basic 6.0.
What If There's No Active
Child Form?
If there's no active child form, attempting
to work with the ActiveMdiChild property of the parent form will trigger
a run-time error. To avoid this situation, you can check the value of the
property in the Click event handler for the Window menu item, and enable or
disable the Center Child Form menu item accordingly. To add this feature,
follow these steps:
1.
With frmMain open in Design
view, press F7 to edit the form's code module.
2.
Select mnuWindow from
the Class Name combo box (the list on the top left of the editor window), and
then select Select from the Method Name combo box (the list on the
right).
3.
Modify the Select event
handler, so that it looks like this:
Private
Sub mnuWindow_Popup( _
ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles mnuWindow.Popup
mnuWCenterChild.Enabled = _
Not (Me.ActiveMdiChild Is Nothing)
End
Sub
4.
4.Run the project, and
verify that if you have child windows displayed, the Center Child Form menu
item is enabled. If there isn't a child form open, verify that the menu item is
disabled.
How does this work? Here are some things to
consider:
- The
Popup event occurs when you select a menu item that includes
sub-items. (You can't use the Click event, since that event doesn't occur
for menu items that contain sub-items.)
- The
Is operator allows you to compare values to the built-in value Nothing.
In this case, the ActiveMdiChild property returns this special
value if it doesn't refer to a form, and you must use the Is operator
to check for this. (The = operator checks values for equality: the Is
operator checks references to objects for equality.)
- The
syntax of the procedure may be confusing. The value in parentheses (Me,
ActiveChild, Is, Nothing) returns a Boolean value:
it's either True or False. The Not operator toggles
the returned value to be the opposite Boolean value. The whole line of
code assigns the return value from the expression in parentheses to the
Enabled property of the menu item. In this case, if it's not true that the
ActiveChild is Nothing, you'll enable the menu item. If it's
True, you'll disable the menu item.
Tracking Child Windows
Visual Basic .NET will keep track of all
child forms that you create, and it's easy to create a window list menu to
manage the child windows. If you wish to see a list of all of the child forms
and be able to give a specific child form focus, follow these steps:
1.
Load frmMain in Design
view.
2.
Select frmMain's Window
menu.
3.
In the Properties window,
set the MdiList to True.
4.
Run the project, open a
couple of Products forms, and then click the Window drop-down menu. You should
see each instance of the Product form that you opened displayed in the window
list.
In most modern Windows applications, you can
click the right mouse button and see a context-sensitive, or shortcut (pop-up),
menu. These menus give you the ability to perform actions based on the current
context—that is, changing depending on the current situation.
Visual Studio provides the ContextMenu
control, making it just as easy to create context menus as it was to create
main menus. Once you've dropped one of these controls on your form (it will
appear in the tray area, just like the MainMenu control did), you can
edit the menu items to be displayed by this context menu.
Note The
design of your context menu won't display on the form until you've clicked the ContextMenu
control. This makes it possible for one form to contain both MainMenu
and ContextMenu controls.
Tip You
can place as many ContextMenu controls as you need on your forms.
To add a context menu to the Products form:
1.
Open frmProducts in Design
view.
2.
In the Toolbox, find the
ContextMenu control.
3.
Double-click this control
to add it to the tray area of the form.
4.
Click the ContextMenu
control to give it focus.
5.
Change the Name property
to cmnuProdID.
6.
Add the menu items (shown
in Table 4) to this control, and set the Name properties as shown. When you add
to a context menu, you start with the first menu item under the top-level menu.
Figure 5 shows the finished context menu.
Table
4. Context menu items
|
Menu
|
Name
|
|
&Lookup
|
mnuPLookUp
|
|
&Copy
|
mnuPCopy
|
|
&Paste
|
mnuPPaste
|
Figure
5. When adding items to the ContextMenu control, create a top-level item that
won't ever be displayed as the parent for your items
1.
Click the Product ID text
box.
2.
In the Properties window,
set the ContextMenu property to the ContextMenu control you just
created, cmnuProdID.
3.
Run the project. On the File
menu, click Products to create a child form, and righ-click on the Product
ID text box to see the context menu appear.
If you were completing this form, you could
now add code to respond to the Click events on each of these menus.
You may need to modify the behavior of menu
items while your application is running. In this section, you'll see how to
check and uncheck, and add and remove menu items programmatically.
To set up for the following sections, you
will need to add three new menu items under the File menu on your MDI
form.
1.
Open frmMain.vb in Design
view.
2.
Click the File menu
to display its sub-items.
3.
Add three menu items, as
described in Table 5.
Table
5. File menu items
|
Menu
|
Name
|
|
&Add
Menus
|
mnuFAddMenus
|
|
&Remove
Menus
|
mnuFRemoveMenus
|
|
&Add
&New Menu
|
mnuFAddNew
|
Checking and Unchecking
Menu Items
Visually selecting a menu item
programmatically is easy: simply set the menu item's Checked property to
True or False, as necessary. For example, you might want to
indicate that you've added new menu items by adding a check to the Add Menus
item, and remove it once you've removed the items. You'll add and remove the
menu items in the next section, but for now, add and remove the check by
following these steps:
1.
On the File menu,
double-click Add Menus to view the Click event procedure.
2.
Modify the event procedure,
so that it looks like this:
Private
Sub mnuFAddMenus_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuFAddMenus.Click
If Not mnuFAddMenus.Checked Then
mnuFAddMenus.Checked = True
End If
End
Sub
3.
To repeat the previous two
steps, on the File menu, double-click Remove Menus and modify its
Click event procedure so that it looks like this:
Private
Sub mnuFRemoveMenus_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuFRemoveMenus.Click
If mnuFAddMenus.Checked Then
mnuFAddMenus.Checked = False
End If
End
Sub
4.
Run the project, and on the
File menu, double-click Add Menus. Verify that you see a check
next to the item. To repeat, on the File menu, click Remove Menus
to verify that the check has been removed.
Adding and Removing Menus
Windows Forms allows you to add and remove
menus programmatically at run time. Using the Add and Remove (or
RemoveAt) methods of the MenuItems collection, you can create new menus
at run time, and delete any menu items.
Note In
Visual Basic 6.0, you could only delete menu items that you created
dynamically, at run time. That is, you couldn't delete static menu items. In
Visual Studio .NET, you can delete any menu item.
Adding Menus
Programmatically
To add a menu item, call the Add
method of a particular menu item. For example, you might want to add two new
menu items on the File menu. To do this, follow these steps:
1.
On the on the File
menu, double-click Add Menus to view its Click event handler.
2.
Modify the event procedure
so that it looks like this:
Private
Sub mnuFAddMenus_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuFAddMenus.Click
If Not mnuFAddMenus.Checked Then
mnuFAddMenus.Checked = True
' Adds these menus to the end of the
File menu
With mnuFile.MenuItems
.Add("New Menu 1")
.Add("New Menu 2")
End With
End If
End
Sub
Each menu item contained within the MainMenu
(or ContextMenu) control is itself a MenuItem object, and just as
with any other object, you refer to the menu items using the Name property you
assigned to each. If a menu item contains other menu items (as each top-level
menu item does), you can use its MenuItems property to refer to the
collection of menu items it contains. In this case, you called the Add
method of a MenuItem object (mnuFile) to add menu items to the
collection of items. (In this example, mnuFile was the name you assigned to the
File menu item.)
Removing Menus
Programmatically
To remove menu items programmatically, you
can either call the MenuItem collection's Remove or RemoveAt
method. Remove requires you to provide a MenuItem object; if you
instead want to remove items by their position within the menu, call the RemoveAt
method.
In this example, the simplest way to remove
the menu items you created in the previous steps is to specify their position
within the menu. You'll call the RemoveAt method to do the work. Because
menu items are numbered starting at 0 (as are all collections and arrays in
Visual Basic .NET), you need to take that into account when removing menu
items.
To handle removing the two menu items you've
just added, modify the Click event procedure for the Remove Menus items
on the File menu, so that the procedure looks like this:
Private
Sub mnuFRemoveMenus_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuFRemoveMenus.Click
If mnuFAddMenus.Checked Then
With mnuFile.MenuItems
' Remove the last two items
.RemoveAt(.Count - 1)
.RemoveAt(.Count - 1)
End With
mnuFAddMenus.Checked = False
End If
End
Sub
Run the project to verify that choosing the Add
and Remove Menus menu items correctly adds and removes the two extra
items.
Using Menu Groups
When you add a check to a menu item, you're
indicating the state of that menu item—it's either selected, or it's not.
Normal checked menus work individually, and are independent of other menu
items.
You may have a need to treat a group of menu
items as a dependent set. In this case, selecting one item from the group
forces all the other items in the group to be deselected. Although Visual
Studio .NET doesn't provide a way to make this happen for you, it does supply
the RadioCheck property of menu items that at least provides a visual
indication. Rather than seeing a normal check, menu items with their RadioCheck
property set to True display a dot when they're selected. It's still up
to your code to deselect all the other items in your menu group, once the user
selects a menu item.
To demonstrate this behavior, modify
properties and add code so that the four window management menu items (Cascade,
Tile Horizontal, Tile Vertical, Arrange Icons) work as a
group. To do that, follow these steps:
1.
With frmMain open in Design
view, select the Window>Center Child Form menu item.
2.
Right-click, and on the
shortcut menu, click Insert Separator, which inserts a separator item
above the selected item.
3.
Click on the Window>Cascade
menu item, then at the same time, press Ctrl and click the other
four window management items on the menu, selecting all four.
4.
In the Properties window,
set the RadioCheck property for the four selected menu items to True.
5.
Add the following procedure
to the frmMain class:
Private
Sub RadioCheck_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuWArrange.Click, mnuWCascade.Click,
_
mnuWHorizontal.Click, mnuWVertical.Click
mnuWArrange.Checked = False
mnuWCascade.Checked = False
mnuWHorizontal.Checked = False
mnuWVertical.Checked = False
CType(sender, MenuItem).Checked = True
End
Sub
6.
Run the project, create
some Product forms, and use the Window menu items to arrange the children. As
you use the Cascade, Tile Horizontal, and other menu items, you
should see a circle next to the most recently selected item. Figure 6 shows the
results of adding this new feature.
Figure
6. Setting a menu item's RadioCheck property to True shows a dot, rather than a
check, next to selected items
It may seem odd that you managed to add new
functionality to four menu items without modifying their event procedures at
all. This example took advantage of a new feature in Visual Basic .NET—you can
hook up as many event handlers to a specific event as you need, using the
Handles clause on a procedure. Here, you provided a new procedure (RadioCheck_Click)
that handles Click events for each of the four menu items you want to have work
together.
Here are the important issues:
- The
procedure you want to call must match the procedure signature of the
standard Click event for menu items. That is, it must receive two
parameters (one as System.Object, the other as System.EventArgs) and
return nothing at all. (It must be a Sub, in other words.)
- You
must add a Handles clause for each event you want to handle. In this case,
you're handling the Click event of four different menu items.
- Within
the procedure, you can use the first parameter (named sender, in
this example) to figure out which object triggered the event. This example
first sets each of the four items to be unchecked, and then checks the item
that triggered the event.
It's also interesting to note how the RadioCheck_Click
procedure set the RadioCheck property of the object it received as its
first parameter. To convert the Object variable into a MenuItem
type, the code calls the CType function, indicating the variable to
convert, and the result type (MenuItem):
CType(sender,
MenuItem).Checked = True
You'll use CType a lot in Visual Basic
.NET. This important function allows you to convert variables from one type to
another. Because Visual Basic .NET is so strictly typed (it's always careful
about the specific data types you're working with, unlike Visual Basic 6.0),
you'll often need to use this function to convert variables into a specific
data type.
Note It's
important to note that when you use the Handles clause as you did here to add
event handlers, you cannot control the order in which those events get handled.
Visual Basic .NET does supply a different mechanism, the AddHandler
statement, which gives you more control. Using the Handles clause is simpler,
however, and if you don't care about the order in which the procedures handle
the event (in this case, you don't), it's an easier way to add extra
functionality.
In this document you have learned to build an
MDI application using several techniques that you find in professional Windows
applications. You also learned to create and manipulate menus. Whether or not
you choose to use the MDI paradigm will depend on the complexity of your
application and how many forms will need to be displayed at one time.







No comments:
Post a Comment