Dynamic menus change at runtime to display more or fewer commands, depending on the current status of the program. This section explores two techniques for implementing dynamic menus:
- Creating short and long versions of the same menu
- Adding and removing menu commands at runtime
Creating Short and Long Menus
A common technique in menu design is to create long and short versions of a menu. If a menu contains many commands, and most of the time only a few of them are needed, you can create one menu with all the commands and another with the most common ones. The first menu is the long one, and the second is the short one. The last command in the long menu should be Short Menu, and when selected, it should display the short version. The last command in the short menu should be Long Menu, and it should display the long version.
Figure 5.17 shows a long and a short version of the same menu for the example the LongMenu Example. The short version omits infrequently used commands and is easier to handle.
Figure 5.17 – The two versions of the Format menu of the LongMenu application
To implement the LongMenu command, start a new project and create a menu with the options shown in Figure 5.17. Listing 5.11 is the code that shows/hides the long menu in the MenuSize command’s Click event.
Listing 5.11: TheMenuSizeMenu Item’s Click Event
Private Sub mnuMenuSize_Click(...) Handles mnuSize.Click If mnuSize.Text = "Short Menu" Then mnuSize.Text = "Long Menu" mnuUnderline.Visible = False mnuStrike.Visible = False mnuSmallCaps.Visible = False mnuAllCaps.Visible = False Else mnuSize.Text = "Short Menu" mnuUnderline.Visible = True mnuStrike.Visible = True mnuSmallCaps.Visible = True mnuAllCaps.Visible = True End If End SubCode language: VB.NET (vbnet)
The subroutine in Listing 5.11 doesn’t do much. It simply toggles the Visible property of certain menu commands and changes the command’s caption to Short Menu or Long Menu, depending on the menu’s current status.
Adding and Removing Commands at Runtime
I conclude the discussion of menu design with a technique for building dynamic menus, which grow and shrink at runtime. Many applications maintain a list of the most recently opened files in the File menu. When you first start the application, this list is empty, and as you open and close files, it starts to grow.
The RunTimeMenu project (Figure 5.18) demonstrates how to add items to and remove items from a menu at runtime. The main menu of the application’s form contains the Run Time Menu submenu, which is initially empty.
Figure 5.18 – Adding and removing menu items at runtime
The two buttons on the form add commands to and remove commands from the Run Time Menu. Each new command is appended at the end of the menu, and the commands are removed from the bottom of the menu first (the most recently added commands are removed first). To change this order and display the most recent command at the beginning of the menu, use the Insert method instead of the Add method to insert the new item. Listing 5.12 shows the code behind the two buttons that add and remove menu items.
Listing 5.12: Adding and RemovingMenu Items at Runtime
Private Sub bttnAddItem_Click(...) Handles bttnAddItem.Click Dim Item As New ToolStripMenuItem Item.Text = "Run Time Option" & _ RunTimeMenuToolStripMenuItem. _ DropDownItems.Count.ToString RunTimeMenuToolStripMenuItem.DropDownItems.Add(Item) AddHandler Item.Click, _ New System.EventHandler(AddressOf OptionClick) End Sub Private Sub bttnRemoveItem_Click(...) Handles bttnRemoveItem.Click If RunTimeMenuToolStripMenuItem.DropDownItems.Count > 0 Then Dim mItem As ToolStripItem Dim items As Integer = _ RunTimeMenuToolStripMenuItem.DropDownItems.Count mItem = RunTimeMenuToolStripMenuItem.DropDownItems(items - 1) RunTimeMenuToolStripMenuItem.DropDownItems.Remove(mItem) End If End SubCode language: VB.NET (vbnet)
The Remove button’s code uses the Remove method to remove the last item in the menu by its index, after making sure the menu contains at least one item. The Add button adds a new item, sets its caption to Run Time Option n, where n is the item’s order in the menu. In addition, it assigns an event handler to the new item’s Click event. This event handler is the same for all the items added at runtime; it’s the OptionClick() subroutine.
All the runtime options invoke the same event handler — it would be quite cumbersome to come up with a separate event handler for different items. In the single event handler, you can examine the name of the ToolStripMenuItem object that invoked the event handler and act accordingly. The OptionClick() subroutine used in Listing 5.13 displays the name of the menu item that invoked it. It doesn’t do anything, but it shows you how to figure out which item of the Run Time Menu was clicked.
Listing 5.13: Programming DynamicMenu Items
Private Sub OptionClick(...) Dim itemClicked As New ToolStripMenuItem itemClicked = CType(sender, ToolStripMenuItem) MsgBox("You have selected the item " & _ itemClicked.Text) End SubCode language: VB.NET (vbnet)
Creating Context Menus
Nearly every Windows application provides a context menu that the user can invoke by right-clicking a form or a control. (It’s sometimes called a shortcut menu or pop-up menu.) This is a regular menu, but it’s not anchored on the form. It can be displayed anywhere on the form or on specific controls. Different controls can have different context menus, depending on the operations you can perform on them at the time.
To create a context menu, place a ContextMenuStrip control on your form. The new context menu will appear on the form just like a regular menu, but it won’t be displayed there at runtime. You can create as many context menus as you need by placing multiple instances of the ContextMenuStrip control on your form and adding the appropriate commands to each one. To associate a context menu with a control on your form, set the control’s ContextMenuStrip property to the name of the corresponding context menu.
Designing a context menu is identical to designing a regular menu. The only difference is that the first command in the menu is always ContextMenuStrip and it’s not displayed along with the menu. Figure 5.19 shows a context menu at design time and how the same menu is displayed at runtime.
Figure 5.19 – A context menu at design time (left) and at runtime (right)
You can create as many context menus as you want on a form. Each control has a ContextMenu property, which you can set to any of the existing ContextMenuStrip controls. Select the control (In Figure 5.19 it is the TextBox control) for which you want to specify a context menu and locate the ContextMenu property in the Properties window. Expand the drop-down list and select the name of the desired context menu.
Figure 5.20 – Created ContextMenuStrip controls at the bottom of the Designer
To edit one of the context menus on a form, select the appropriate ContextMenuStrip control at the bottom of the Designer as shown in Figure 5.20. The corresponding context menu will appear on the form’s menu bar, as if it were a regular form menu. This is temporary, however, and the only menu that appears on the form’s menu bar at runtime is the one that corresponds to the MenuStrip control (and there can be only one of them on each form).