Menus have always been a part of Windows Forms applications. They give the user quick and easy access to important application commands in an easy-to-understand, easy-to-browse interface. The .NET Framework version 2.0 introduced MenuStrips, which allow the rapid creation of Forms menus as well as context menus (also known as shortcut menus, which appear when the user right-clicks an object). In this lesson, you will learn how to create menus and context menus and configure them for use in your application.
After this lesson, you will be able to:
■ Create and configure a MenuStrip component on a Windows Form.
■ Change the Displayed menu structure programmatically.
■ Create and configure the ContextMenuStrip component on a Windows Form.
Estimated lesson time: 30 minutes
Overview of the MenuStrip Control
The MenuStrip control is essentially a ToolStrip control that is optimized for the dis
play of ToolStripMenuItems. The MenuStrip control derives from ToolStrip and can host all of the tool strip items described in the previous lesson. Its primary function, how
ever, is to host ToolStripMenuItems.
ToolStripMenuItems are the controls that provide the visual representation for items on a menu. They can appear as text, an image, or both, and can execute code found in their ToolStripMenuItem.Click event handlers when clicked. Each ToolStripMenuItem can contain its own set of menu items, allowing for the creation of nested menus.
The menu strip exposes many properties that affect the behavior of its hosted Tool- StripMenuItems. Important properties of the MenuStrip control are shown in Table 4-5.
Table 4-5 Important Properties of the MenuStrip Control
Property Description
AllowItemReorder Indicates whether items can be reordered by the user.
When set to True, contained items can be reordered when the user holds down the Alt key and grabs the item with the mouse.
Table 4-5 Important Properties of the MenuStrip Control
Property Description
AllowMerge Indicates whether this menu strip can be merged with another tool strip.
Dock Indicates how the menu strip is docked. Although Menu- Strip controls can be free in the form, they are most com
monly docked to one of the form edges.
LayoutStyle Indicates how the controls on the tool strip are laid out. A value of HorizontalStackWithOverFlow indicates that items are stacked horizontally and overflow as needed. Vertical- StackWithOverFlow stacks items vertically and overflows as needed. StackWithOverflow determines the stack model appropriate to the Dock property of the tool strip. Flow allows the items to stack horizontally or vertically as needed, and Table arranges all of the items flush left.
RenderMode Determines how the tool strip items are rendered. System uses system settings, Professional indicates a Microsoft Office–style appearance, and ManagerRenderMode gets the setting automatically.
ShowItemToolTips Indicates whether tooltips for individual tool strip items are displayed.
Stretch When hosted in a ToolStripContainer, it indicates whether the tool strip will stretch to the full length of the ToolStrip- Panel.
TextDirection Indicates the direction of the text in controls hosted in the tool strip.
Note that the properties of the MenuStrip control are very similar to the properties of the ToolStrip control. Because MenuStrip derives from ToolStrip, it exposes most of the same properties as the ToolStrip control and encapsulates most of the same functionality.
ToolStripMenuItems provide all of the functionality that is expected of menus. Table 4-6 explains some of the important properties of the ToolStripMenuItem control.
Table 4-6 Important Properties of the ToolStripMenuItem Control
Property Description
AutoSize Determines whether the menu item is automatically sized to fit the text.
Checked Determines whether the menu item appears as checked.
CheckOnClick Determines whether the menu item is automatically checked when clicked.
CheckState Returns the CheckState of the menu item. The CheckState can be Checked, Unchecked, or Indeterminate.
DisplayStyle Determines how the tool strip menu item is displayed. This property can be set to None, which provides no visual repre
sentation; Text, which shows only text; Image, which dis
plays the item only with an image; or ImageAndText, which displays the image next to the text.
DoubleClickEnabled Determines whether the DoubleClick event will fire.
DropDownItems Contains a collection of tool strip items (usually tool strip menu items but not necessarily) that appear in the drop- down list when this item is chosen.
Enabled Determines whether the tool strip menu item is enabled.
Image Sets the image to be associated with this tool strip menu item.
MergeAction Determines the action taken by this tool strip menu item when menus are merged.
MergeIndex Determines the order of items in the resultant menu after menus are merged.
ShortcutKeyDisplay- String
Sets a custom string for the shortcut key that is displayed next to the menu item. If shortcut keys are enabled and this property is left blank, the actual key combination will be displayed.
Table 4-6 Important Properties of the ToolStripMenuItem Control
Property Description
ShortcutKeys Defines the key combination that will act as a shortcut to execute the menu command.
ShowShortcutKeys Indicates whether shortcut keys are enabled.
Text Gets or sets the text displayed in the menu item.
TextImageRelation Determines how the text and image are displayed together when the DisplayStyle property is set to ImageAndText.
Creating Menu Strips and Tool Strip Menu Items
You can create a MenuStrip at design time in the same way that you create any control:
by dragging it from the Toolbox onto the design surface. Once added to the design surface, an interface for creating tool strip menu items appears. You can type a string into the box in the menu strip to create a new tool strip menu item. After a new item has been created, additional boxes appear to the right and beneath the newly created tool strip menu item to allow you to create more items or sub-items of the first item.
This interface disappears if you move the focus elsewhere in the designer, but you can make it reappear by clicking the tool strip menu item. The ToolStripMenuItem control design interface is shown in Figure 4-3.
Figure 4-3 The ToolStripMenuItem control design interface
Note that the default naming scheme for the ToolStripMenuItem control is different from the default naming scheme for other controls. Although controls such as Button are appended with a number when added to the form (such as Button1), tool strip menu
items are prepended with the text of the menu item. For example, if you created a File menu item, the default name would be FileToolStripMenuItem. You can rename a menu item by changing the Name property in the Properties window.
Changing Properties for Multiple Tool Strip Menu Items at Once
At times, you might want to edit properties for several menu items (or any control) at the same time. This is generally done to ensure that all controls have the same set
ting for a particular property. If you edit properties for different types of controls, the Properties window displays only those properties and events that all controls have in common.
� To change multiple menu item properties at once
1. While holding down the Ctrl key, click each menu item you want to edit to select it.
2. Make the appropriate changes in the Properties window. Changes you make will be made to all selected menu items.
You can also add tool strip menu items to menu strips programmatically at run time.
You can either add a pre-existing menu item (for example, an item on another menu strip) or create a brand new menu item and add it to the menu strip. The following code example demonstrates each of these techniques.
' VB
' Adds an existing ToolStripMenuItem to the MenuStrip MenuStrip1.Items.Add(OpenToolStripMenuItem)
' Creates a new ToolStripMenuItem and adds it to the MenuStrip Dim HelpToolStripMenuItem As New ToolStripMenuItem("Help") MenuStrip1.Items.Add(HelpToolStripMenuItem)
// C#
// Adds an existing ToolStripMenuItem to the MenuStrip menuStrip1.Items.Add(OpenToolStripMenuItem);
// Creates a new ToolStripMenuItem and adds it to the MenuStrip ToolStripMenuItem HelpToolStripMenuItem = new
ToolStripMenuItem("Help");
menuStrip1.Items.Add(HelpToolStripMenuItem);
You can also use the MenuStrip.Items.Add method to add new tool strip menu items even if you don’t have a reference to an existing tool strip menu item. The following example shows how you can specify text or an image to create a tool strip menu item and get a reference to it.
' VB
Dim newMenuItem1 As ToolStripMenuItem Dim newMenuItem2 As ToolStripMenuItem
' Adds a new menu item by specifying text newMenuItem1 = MenuStrip1.Items.Add("File") ' Adds a new menu item by specifying an image newMenuItem2 = MenuStrip1.Items.Add(anImage)
// C#
ToolStripMenuItem newMenuItem1;
ToolStripMenuItem newMenuItem2;
// Adds a new menu item by specifying text newMenuItem1 = MenuStrip1.Items.Add("File");
// Adds a new menu item by specifying an image newMenuItem2 = MenuStrip1.Items.Add(anImage);
You can use similar techniques to add new or existing tool strip menu items to the drop-down items of an existing tool strip menu item. This has the effect of creating new items in a sub-menu. The following example demonstrates programmatically adding a tool strip menu item to the DropDownItems collection of an existing tool strip menu item:
' VB
Dim newMenuItem1 As ToolStripMenuItem Dim newMenuItem2 As ToolStripMenuItem
' Adds an existing ToolStripMenuItem to another existing ToolStripMenuItem FileToolStripMenuItem.DropDownItems.Add(OpenToolStripMenuItem)
' Creates a new ToolStripMenuItem and adds it to the MenuStrip Dim HelpToolStripMenuItem As New ToolStripMenuItem("Help") FileToolStripMenuItem.DropDownItems.Add(HelpToolStripMenuItem) ' Adds a new menu item by specifying text
newMenuItem1 = FileToolStripMenuItem.DropDownItems.Add("Open") ' Adds a new menu item by specifying an image
newMenuItem2 = FileToolStripMenuItem.DropDownItems.Add(anImage)
// C#
ToolStripMenuItem newMenuItem1;
ToolStripMenuItem newMenuItem2;
// Adds an existing ToolStripMenuItem to another existing ToolStripMenuItem FileToolStripMenuItem.DropDownItems.Add(OpenToolStripMenuItem);
// Creates a new ToolStripMenuItem and adds it to the MenuStrip
ToolStripMenuItem HelpToolStripMenuItem = new ToolStripMenuItem("Help");
FileToolStripMenuItem.DropDownItems.Add(HelpToolStripMenuItem);
// Adds a new menu item by specifying text
newMenuItem1 = (ToolStripMenuItem)FileToolStripMenuItem.DropDownItems.Add("Open");
// Adds a new menu item by specifying an image
newMenuItem2 = (ToolStripMenuItem)FileToolStripMenuItem.DropDownItems.Add(anImage);
Copying Menu Items at Design Time
At times, you might want to copy menu items from one location to another. For exam
ple, if you are creating different menus but you want to have a common set of options
between them, you can easily copy menu items by copying and pasting in the designer.
� To copy menu items at design time
1. In the Designer, right-click the menu item you want to copy and choose Copy from the context menu.
2. In the Designer, right-click the menu item that is the intended location of the copied menu and choose Paste from the context menu. The menu item is copied into the new location.
Note that you can copy top-level items to sub-level items, sub-level items to top-level items, top-level items to top-level items, or sub-level items to sub-level items with this procedure.
Adding Enhancements to Menus
Menus are capable of displaying a variety of enhancements that streamline the user experience and enhance usability. This section will cover how to create check marks, access keys, separator bars, and shortcut keys on menu items.
Adding Check Marks to Menu Items
You can display check marks next to any menu item except a top-level menu item.
This is useful when you want to indicate to the user that a menu option is selected or enabled. You can display a check mark beside a menu item by setting the Checked property to True, as shown here:
' VB
OptionToolStripMenuItem.Checked = True
// C#
optionToolStripMenuItem.Checked = true;
Alternatively, you can define whether the menu item is selected by setting the CheckState property to Checked, as shown here:
' VB
OptionToolStripMenuItem.CheckState = CheckState.Checked
// C#
optionToolStripMenuItem.CheckState = CheckState.Checked;
The Checked property is a Boolean property that returns whether an item is checked.
If the item is checked, the Checked property returns True. If the item is in any other
state, the Checked property returns False. The CheckState property on the other hand, indicates the actual state of the menu item and will return either CheckState.Checked, CheckState.UnChecked, or Checkstate.Indeterminate.
If you want a menu item to appear checked when the user clicks the item, you can set the CheckOnClick property to True. This will cause the check mark on the menu item to toggle between checked and unchecked each time the user clicks the menu item. You can programmatically change the check state or determine if the menu item is checked using the ToolStripMenuItem.CheckState or ToolStripMenuItem.Checked properties.
Adding Separator Bars to Menus
It can be useful to add separator bars to menus to set groups of menu options apart from each other. You can add a separator to any sub-menu at design time by choos
ing Separator from the drop-down box in the menu item design interface, as shown in Figure 4-4.
Figure 4-4 Choosing a separator in the menu item design interface
Note that if you want to add a separator to a top-level menu, you must do so program
matically by creating a new instance of the ToolStripSeparator control and inserting it into the correct location in the MenuStrip.Items collection, as shown here:
' VB
Dim aSeparator As New ToolStripSeparator MenuStrip1.Items.Insert(1, aSeparator)
// C#
ToolStripSeparator aSeparator = new ToolStripSeparator();
menuStrip1.Items.Insert(1, aSeparator);
Creating Access Keys
Access keys enable you to access menu items by defining keys that, when pressed in combination with the Alt key, will execute the menu command. For example, if a File menu defines the F key as an access key, when Alt+F is pressed, the File menu will open. Menus that contain sub-menus open when the access key combination is pressed, and menus that invoke commands will invoke those commands. Note that the menu item must be visible for the access key to function. Thus, if you define an access key for an Open menu item that exists in the File sub-menu, the File menu must be opened first for the access key combination to function.
You can create an access key for a menu by preceding the letter you want to define the access key for with an ampersand (&) symbol. For example, to create an Alt+F access key combination for the File menu, you would set the FileToolStripMenuItem’s Text property to &File.
Creating Shortcut Keys
Unlike access keys, shortcut keys are a combination of keystrokes that allow direct invocation of a menu item whether the menu item is visible or not. For example, you might define the Ctrl+E key combination to be a shortcut key for the Exit menu com
mand in the File menu. Even if the File menu is not open, Ctrl+E will cause the Exit menu command to be executed. Also, unlike access keys, you cannot create shortcut keys for top-level menus—you can create them only for items in sub-menus.
You can create a shortcut key at design time by setting the ShortcutKeys property in the Properties window. Clicking the ShortcutKeys property launches a visual interface than enables you to define a key combination. This interface is shown in Figure 4-5.
If you want to display the shortcut key combination next to the menu item, you can set the ShowShortcutKeys property of the ToolStripMenuItem control to True. You can also define a custom text to be shown instead of the key combination. If you want to define a custom text, you can set it in the ShortcutKeyDisplayString property.
Figure 4-5 The ShortcutKeys property user interface
Moving Items Between Menus
You can move items from one menu to another at run time. This allows you to dynam
ically customize menus for special purposes. You can move a menu item to a new menu strip by using the MenuStrip.Items.Add method to add it to the new menu strip.
It will be removed from the previous menu strip automatically. If you want to add the menu item to a particular location in the new menu strip, you can use the Insert method to add it at a particular index. Examples are shown here:
' VB
' Adds the FileToolStripMenuItem
MenuStrip2.Items.Add(FileToolStripMenuItem)
' Inserts FileToolStripMenuItem to the location corresponding to index 1 MenuStrip2.Items.Insert(1, FileToolStripMenuItem)
// C#
// Adds the FileToolStripMenuItem
menuStrip2.Items.Add(FileToolStripMenuItem);
// Inserts FileToolStripMenuItem to the location corresponding to index 1 menuStrip2.Items.Insert(1, FileToolStripMenuItem);
You can also use the analogous methods of the ToolStripMenuItem.DropDownItems property to move items from one menu to another. Examples are shown here:
' VB
' Adds the FileToolStripMenuItem
AppToolStripMenuItem.DropDownItems.Add(FileToolStripMenuItem)
' Inserts FileToolStripMenuItem to the location corresponding to index 1 AppToolStripMenuItem.DropDownItems.Insert(1, FileToolStripMenuItem)
// C#
// Adds the FileToolStripMenuItem
AppToolStripMenuItem.DropDownItems.Add(FileToolStripMenuItem);
// Inserts FileToolStripMenuItem to the location corresponding to index 1 AppToolStripMenuItem.DropDownItems.Insert(1, FileToolStripMenuItem);
Disabling, Hiding, and Deleting Menu Items
At times, it makes sense to remove certain options from a menu. You might want a menu item to be disabled when conditions aren’t appropriate for it to be invoked or to hide a menu item that shouldn’t be displayed. In some cases, you might want to delete a menu item completely from a menu.
You can disable a menu item by setting the Enabled property to False. This will cause the menu item to appear dimmed. It will still be visible to the user, but it cannot be invoked by mouse clicks or keystrokes.
You can hide a menu item by setting the Visible property to False. This will keep the menu item from appearing in the menu. Note, however, that it does not disable the menu item, and if the Enabled property is set to True, the menu item can still be invoked through shortcut keys if they have been defined for this menu item. Hide menu items sparingly; if a user is looking for a specific menu item, it is typically better for them to see it dimmed because the Enabled property has been set to False. Other
wise, they might continue looking for the hidden menu item on other menus.
If you need to delete a menu item from a menu entirely, you can do so by using the MenuStrip.Items.Remove and MenuStrip.Items.RemoveAt methods to remove an item from a top-level menu or the ToolStripMenuItem.DropDownItems.Remove and ToolStrip- MenuItem.DropDownItems.RemoveAt methods to remove an item from a sub-menu, as shown in the following examples:
' VB
'Removes FileToolStripMenuItem from MenuStrip1 MenuStrip1.Items.Remove(FileToolStripMenuItem)
' Removes FileToolStripMenuItem from AppToolStripMenuItem AppToolStripMenuItem.DropDownItems.Remove(FileToolStripMenuItem) ' Removes the ToolStripMenuItem at index 4 from MenuStrip1 MenuStrip1.Items.RemoveAt(4)
' Removes the ToolStripMenuItem at index 4 from AppToolStripMenuItem
AppToolStripMenuItem.DropDownItems.RemoveAt(4)
// C#
// Removes FileToolStripMenuItem from menuStrip1 menuStrip1.Items.Remove(FileToolStripMenuItem);
// Removes FileToolStripMenuItem from AppToolStripMenuItem
AppToolStripMenuItem.DropDownItems.Remove(FileToolStripMenuItem);
// Removes the ToolStripMenuItem at index 4 from menuStrip1 menuStrip1.Items.RemoveAt(4);
// Removes the ToolStripMenuItem at index 4 from AppToolStripMenuItem AppToolStripMenuItem.DropDownItems.RemoveAt(4);
Merging Menus
Menus can be merged at run time and their items incorporated into a single menu. You can merge MenuStrips, ContextMenuStrips (which are covered in greater detail later in this lesson), or both. In fact, you can even merge MenuStrip controls with ToolStrip con
trols. Like merging tool strips, merging menu strips is accomplished by invoking the ToolStripManager.Merge method on the static ToolStripManager class, as shown here:
' VB
ToolStripManager.Merge(sourceMenuStrip, targetMenuStrip)
// C#
ToolStripManager.Merge(sourceMenuStrip, targetMenuStrip);
The preceding example takes the first menu strip, sourceMenuStrip, and merges it with the second menu strip (targetMenuStrip). The tool strip menu items on sourceMenuStrip are then merged with the items on targetMenuStrip as determined by their MergeAction property value. Table 4-7 summarizes the merge action taken by MergeAction property value.
Table 4-7 ToolStripItem MergeAction Property Values and Merge Actions MergeAction Value Action Taken
Append Appends the item at the end of the list of items.
Insert Inserts the item at the location specified by the MergeIndex property.
MatchOnly Looks for a match but takes no action.
Remove If a matching tool strip item is found, it is removed from the resulting tool strip.