Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Visual Basic 2005 Express Edition - From Novice To Professional (2006)

.pdf
Скачиваний:
387
Добавлен:
17.08.2013
Размер:
21.25 Mб
Скачать

300 C H A P T E R 1 1 M E N U S A N D T O O L B A R S

If you click in the Image property, you’ll see the usual ellipsis button appear that lets you choose the image to set against the control. When you click the button, the Select Resource dialog appears, shown in Figure 11-11.

Figure 11-11. The Select Resource dialog

Images used inside menus must be included in the final compiled program; they can’t be external files that live anywhere on the hard disk. So when you click to choose an image to set, the resource dialog appears, showing you images that are going to be embedded into your final compiled program. You can use this dialog to choose other images from the hard disk, and in doing so you’ll add those images to a special folder in the Solution Explorer called Resources.

You can probably guess what the ImageAlign property does. It controls where in the menu item the image appears. Well, almost. It sets up where the image appears in the image part of the menu. Click on a menu in the designer, for example, and you’ll see a shaded area to the left of the text. This is where any images get displayed, and the ImageAlign property controls where in that area the image appears. Most people leave it at MiddleCenter.

The ImageTransparentColor property is a strange one at first. When you load in an image—any image—it is likely to have a background color. Menu items also have a background color. As a result, images added to the menu could stand out horribly if the background color of the image and background color of the menu clash. The ImageTransparentColor property lets you specify a color in the image to ignore. When the menu is drawn, the color specified is never drawn, and as a result the background color and shading of the menu item itself shows through. The best way to determine the value to place into this property is to load the image in question into a drawing program such as

C H A P T E R 1 1 M E N U S A N D T O O L B A R S

301

Microsoft Paint. Within Microsoft Paint, you can click the pipette icon and then click on the background color to select it. You can then select the Colors menu and choose Edit Colors to see the color value. You can see an example of this in Figure 11-12.

Figure 11-12. You can use a program such as Microsoft Paint to determine the background color value. In this case the color is 255,0,255.

After you have found out the background color (in this case 255,0,255), just key that into the ImageTransparentColor property. Instantly the background of the image in the menu will vanish.

Finally, the ImageScaling property of a menu item works hand in hand with the MenuStrip control’s own ImageScalingSize properties. If you click on a MenuStrip control and look at its properties, you’ll notice that by default the ImageScalingSize property is set to 16, 16. This means that images are a standard 16 dots (pixels) wide and 16 dots high. Setting ImageScaling of a menu item to SizeToFit makes the menu item resize any image you select so that it fits this size.

BACKGROUND COLORS AND THE MICROSOFT IMAGE LIBRARY

Visual Basic 2005 Express ships with a set of graphics known as the Image Library. You can find it in your VB Express directory, which is typically C:\Program Files\Microsoft Visual Studio 8\Common7\VS2005ImageLibrary.

All the images Microsoft includes have a background color value of 255,0,255, which makes using them and setting them up inside your own applications nice and easy.

302 C H A P T E R 1 1 M E N U S A N D T O O L B A R S

Let’s take a look at all this with a “Try It Out,” and also see how to set menu shortcuts, key combinations that when pressed instantly click a menu item without the user having to mouse around to do it the hard way.

Try It Out: Adding Images and Shortcuts to a Menu

Let’s go back to the menu you built earlier in the chapter. You’ll add some graphics and shortcuts to it.

In the designer, select the Open item under the File menu so that its properties are displayed in the Properties window. Click the ellipsis button next to the Image property to open up the resources dialog you saw earlier, and then click the Import button. A typical file Open dialog will appear, as in Figure 11-13.

Figure 11-13. Clicking the Import button on the resources dialog opens up a standard file dialog.

Use the dialog to find an image on your hard disk. If you have the Visual Studio Image Library installed, go to its location and choose an image; I used the OpenFolder.bmp file.

C H A P T E R 1 1 M E N U S A N D T O O L B A R S

303

After you have chosen an image, you’ll be returned to the resource dialog. Click the image you just chose and then close the dialog. The menu item will redraw with the selected image, just as in Figure 11-14.

Figure 11-14. As soon as you choose an image by using the resource dialog, the image gets drawn into the menu.

It probably looks pretty horrible at the moment, because you haven’t set the ImageTransparentColor property. Use your favorite paint package to find out the what the color value is, and then key the value into the ImageTransparentColor property. If you are using images from the Image Library that comes with VB Express, the value will either be 255,0,255 (if the icon appears with a bright pink background) or 0 (if you see it on a black background). Key this into the ImageTransparentColor property, and the menu will once again redraw to remove the background color.

Repeat the process a couple of times to get used to working with images, and set up the images for the Save and Exit menu items. My menu looks like Figure 11-15.

Figure 11-15. It’s best not to go crazy and put images on every single menu item. That just gets confusing. A few images, though, can make key menu items really stand out.

304 C H A P T E R 1 1 M E N U S A N D T O O L B A R S

Next, let’s add some shortcuts. Shortcuts are really nothing to do with images, but like images in a menu, they do make menu items stand out, telling the user what key combinations can be used to invoke certain key operations within the program. After you set a shortcut key into a menu, that key combination will automatically invoke the menu item without you having to write any extra code to manage it.

Select the Open menu item once again, and then click its ShortcutKeys property in the Properties window. The rather neat mini dialog in Figure 11-16 appears.

Figure 11-16. Clicking in the ShortcutKeys property displays a handy dialog to let you easily set up the menu item’s shortcut key.

The shortcut for Open in most applications is Ctrl+O. So click the Ctrl check box in the dialog, and then choose O (for Orange) from the drop-down. When you’re finished, the menu will redraw to look like Figure 11-17.

Figure 11-17. As soon as you set a shortcut key for a menu item, the item redraws to show you what the user will see at runtime.

Go ahead now and set the shortcuts for the other menu items: Save should be Ctrl+S, Save As should be Ctrl+Shift+S, and Exit should be Ctrl+X. The finished menu will look like mine in Figure 11-18.

C H A P T E R 1 1 M E N U S A N D T O O L B A R S

305

Figure 11-18. The finished menu, with all the shortcut keys set

Just as with images, it’s not a good idea to go overboard and set up shortcut keys for every single menu item; it looks horrible and it confuses users. Choose the most important and commonly used menu items in the program and just set the shortcuts for them. In addition, pay attention to the shortcuts used by other Windows programs. The more familiar your program appears to be, the quicker users will take to it and love it.

Menus in an MDI Application

Hopefully you’re quite happy with how to build menus by now, even pretty graphical ones with handy shortcut keys attached. The problem with menus really comes into play when you start implementing fairly complex MDI-type applications. Or at least, it used to.

You see, with an MDI application, the menu is hosted in the parent window. So when the user clicks on a menu item such as Save, you need to figure out in code just which window is currently open, and which document the user wants to save. In addition, though, you might not want certain menu items to be activated for all of the windows. It doesn’t make any sense, for example, to have the Save menu item working when the user doesn’t have any child windows open. Finally, you may want certain windows to add new menu items to the main menu bar, depending on the kind of data that those windows hold.

This sort of thing used to be a nightmare that would invariably result in loads of potentially buggy code (because the more code you write, the more chances you’ll make mistakes). Not so anymore, thank goodness.

Rather than just talk you through all the potential solutions to these issues, let’s just dive straight into a “Try It Out,” where we’ll put your newfound menu-building skills to good use.

306 C H A P T E R 1 1 M E N U S A N D T O O L B A R S

Try It Out: Menus and MDI Applications

Start up a new WinForms project and set the IsMDIContainer property of Form1 to True. You’ll recall from the preceding chapter that this turns a form into an MDI parent form.

Drop a MenuStrip control onto the form and build a file menu like the one in Figure 11-19 (don’t worry about setting the images if you don’t want to—it won’t affect the program at all).

Figure 11-19. Build a file menu on the MDI form, like this.

Next, add a new window to the application and call it ChildForm.vb. Add a menu strip to this form and set it up like the one in Figure 11-20. (Again, don’t worry too much about putting images into the menu items if you don’t want to.)

Figure 11-20. Set up the menu on the new child form, like this.

Set the names of the new menu items to setToRed, setToBlue, and setToGreen, appropriately, and you’re ready to code. First, let’s code up the child form. When the user clicks on any of the menu items, you want to change the color of the form. Double-click each menu item to drop into the code editor, and write

C H A P T E R 1 1 M E N U S A N D T O O L B A R S

307

some code to change the BackColor property of the form. When you’re finished, you’ll have three event handlers that should look like this (I’ve highlighted the lines you need to add, as usual):

Public Class ChildForm

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

ByVal e As System.EventArgs) Handles setToRed.Click

Me.BackColor = Color.Red

End Sub

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

ByVal e As System.EventArgs) Handles setToBlue.Click

Me.BackColor = Color.Blue

End Sub

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

ByVal e As System.EventArgs) Handles setToGreen.Click

Me.BackColor = Color.Green

End Sub

End Class

Now, if this were a real application, you’d also want the child form to have a way to save its data. In the code editor add another method, a public one called Save():

Public Sub Save()

MessageBox.Show("I have saved my data!")

End Sub

308 C H A P T E R 1 1 M E N U S A N D T O O L B A R S

What’s going to happen is that when the Save menu item on the parent form is clicked, you are going to get the parent form to find out which child window is currently active and then call the child window’s Save() method. Later in the book you’ll see how to actually read and write files and databases, but for now you’ll stick with a simple message box to show that something happened.

Go back to the designer for the MDI parent form now and double-click the New menu item. When this is clicked, you want to create a new MDI child window, something that you’ll remember from the preceding chapter is really nice and easy to do. The code for the event handler looks like this:

Public Class Form1

Private Sub NewToolStripMenuItem_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles NewToolStripMenuItem.Click

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

End Sub

End Class

How about the Save item now? Go back to the designer and double-click the Save menu item and code it up like this:

Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles SaveToolStripMenuItem.Click

Dim formToSave As ChildForm

formToSave = CType(Me.ActiveMdiChild, ChildForm) formToSave.Save()

End Sub

You can look at the ActiveMdiChild property of a form to get the child form that’s currently active. All you need to do when the user clicks Save, then, is cast this value to a ChildForm object (ActiveMdiChild just gives you a basic form object, so you use CType to cast this to a specific type of form), and then call the Save() method you wrote a short while ago.

You’re nearly finished, but there’s a problem. If you run the program now, you’ll find that the Save item is always shown and clickable. In fact, if you run the program right now and click the Save item, the program will crash. Why? Well, there isn’t an active child window open, so you’re trying to call Save() on an object that doesn’t really exist. What you need is a way to change the menu structure slightly based on what state the program is currently in.

C H A P T E R 1 1 M E N U S A N D T O O L B A R S

309

Go back to the designer view of the MDI form and click the File menu item itself (not any of its children). Take a look at the list of events that a menu can respond to in the Properties window (Figure 11-21).

Figure 11-21. The events that a menu item can respond to

Two events in particular stand out: DropDownOpened and DropDownOpening. The DropDownOpened event occurs after the user clicks on a menu and its child menu items have been displayed. DropDownOpening,

on the other hand, occurs when the user clicks on a menu item, immediately before the child menu items are displayed. You can use this event to change the state of the Save menu based on what the program is currently up to.

Double-click the DropDownOpening event for the File menu to drop into the code editor.

There is an array attached to an MdiParent form like this one, called MdiChildren. If this array is empty, its length property will be zero. You can use this to enable or disable the Save menu item. Type some code in:

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

ByVal e As System.EventArgs) Handles FileToolStripMenuItem.DropDownOpening

If Me.MdiChildren.Length = 0 Then

SaveToolStripMenuItem.Enabled = False

Else

SaveToolStripMenuItem.Enabled = True

End If

End Sub