Walkthrough: Adding a Menu Controller to a Toolbar
This walkthrough builds on the Walkthrough: Adding a Toolbar to a Tool Window (C#) walkthrough and guides you through the steps of adding a menu controller to the tool window's toolbar. The steps shown here also can be applied to the toolbar created in the Walkthrough: Adding a Toolbar to the IDE, if desired.
A menu controller is a split control. The left side of the menu controller shows the last-used command, and it can be run by clicking it. The right side of the menu controller is a drop-down arrow that, when clicked, opens a drop-down list of additional commands. When you click a command on the list, the command runs, and it replaces the command on the left side of the menu controller. In this way, the menu controller operates like a command button that always shows the last-used command from a list.
Menu controllers can appear on menus but they are most often used on toolbars.
This walkthrough demonstrates a menu controller that offers three selectable options which are added by using .vsct files. For more information on menus and .vsct files, see Menus and Toolbars.
Note
Beginning with Visual Studio 2008 SDK, use XML Command Table (.vsct) files instead of command table configuration (.ctc) files to define how menus and commands appear in your VSPackages. For more information, see Visual Studio Command Table (.Vsct) Files
Prerequisites
This walkthrough requires the Visual Studio Industry Partner (VSIP) SDK to be installed.
Creating a Menu Controller
To create a menu controller
- Follow the procedures described in Walkthrough: Adding a Toolbar to a Tool Window (C#) to create a tool window VSPackage with a toolbar.
Note
The rest of the procedures in this walkthrough use the VSPackage name TWToolbar, which is the name used in the Walkthrough: Adding a Toolbar to a Tool Window (C#) walkthrough.
In Solution Explorer, double-click TWToolbar.vsct to open it in a text editor.
In the Symbols Element, in the GuidSymbol Element named "guidTWToolbarCmdSet", declare your menu controller, menu controller group, and three menu items.
<IDSymbol name="TestMenuController" value="0x1300"/> <IDSymbol name="TestMenuControllerGroup" value="0x1060"/> <IDSymbol name="cmdidMCItem1" value="0x0130"/> <IDSymbol name="cmdidMCItem2" value="0x0131"/> <IDSymbol name="cmdidMCItem3" value="0x0132"/>
In the Menus Element, define the menu controller as a menu.
<Menu guid="guidTWToolbarCmdSet" id="TestMenuController" priority="0x0100" type="MenuController"> <Parent guid="guidTWToolbarCmdSet" id="TWToolbarGroup"/> <CommandFlag>IconAndText</CommandFlag> <CommandFlag>TextChanges</CommandFlag> <CommandFlag>TextIsAnchorCommand</CommandFlag> <Strings> <ButtonText>Test Menu Controller</ButtonText> <CommandName>Test Menu Controller</CommandName> </Strings> </Menu>
The TextChanges and TextIsAnchorCommand flags must be included for the menu controller to reflect the last selected command.
In the Groups Element, after the last group entry, add the menu controller group.
<Group guid="guidTWToolbarCmdSet" id="TestMenuControllerGroup" priority="0x000"> <Parent guid="guidTWToolbarCmdSet" id="TestMenuController"/> </Group>
By setting the menu controller as the parent, any commands placed in this group will appear in the menu controller. The priority attribute is omitted, which sets it to the default value of 0, because it will be the only group on the menu controller.
In the Buttons Element, after the last button entry, add a Button Element for each of your menu items.
<Button guid="guidTWToolbarCmdSet" id="cmdidMCItem1" priority="0x0000" type="Button"> <Parent guid="guidTWToolbarCmdSet" id="TestMenuControllerGroup"/> <Icon guid="guidTWToolbarCmdSet" id="bmpPic1"/> <CommandFlag>IconAndText</CommandFlag> <Strings> <ButtonText>MC Item 1</ButtonText> <CommandName>MC Item 1</CommandName> </Strings> </Button> <Button guid="guidTWToolbarCmdSet" id="cmdidMCItem2" priority="0x0100" type="Button"> <Parent guid="guidTWToolbarCmdSet" id="TestMenuControllerGroup"/> <Icon guid="guidTWToolbarCmdSet" id="bmpPic2"/> <CommandFlag>IconAndText</CommandFlag> <Strings> <ButtonText>MC Item 2</ButtonText> <CommandName>MC Item 2</CommandName> </Strings> </Button> <Button guid="guidTWToolbarCmdSet" id="cmdidMCItem3" priority="0x0200" type="Button"> <Parent guid="guidTWToolbarCmdSet" id="TestMenuControllerGroup"/> <Icon guid="guidTWToolbarCmdSet" id="bmpPicSmile"/> <CommandFlag>IconAndText</CommandFlag> <Strings> <ButtonText>MC Item 3</ButtonText> <CommandName>MC Item 3</CommandName> </Strings> </Button>
At this point, you can look at the menu controller.
Press F5 to open an instance of the experimental Visual Studio.
On the View menu, point to Other Windows, and then click Test Tool Window.
The menu controller appears in the toolbar in the tool window.
Click the down arrow on the right-hand side of the menu controller to see the three possible commands.
Notice that when you click a command, the left-hand side of the menu controller changes to display that command. In the next section, we will add the code to activate these commands.
Close the experimental Visual Studio.
Implementing the Menu Controller Commands
To implement the menu controller commands in managed code
In Solution Explorer, double-click PkgCmdID.cs to open it in a text editor.
After the existing command IDs in the PkgCmdIDList class, add command IDs for your three menu items.
public const int cmdidMCItem1 = 0x130; public const int cmdidMCItem2 = 0x131; public const int cmdidMCItem3 = 0x132;
In Solution Explorer, open TWToolbarPackage.cs.
At the top of the TWToolbarPackage class, add the following:
private int currentMCCommand; // The currently selected menu controller command
Locate the hidden region labeled "Package Members" and expand it by clicking the plus sign in the left margin.
In the Initialize method, immediately after the last call to the AddCommand method, add code to route the events for each command through the same handlers.
for (int i = PkgCmdIDList.cmdidMCItem1; i <= PkgCmdIDList.cmdidMCItem3; i+) { CommandID cmdID = new CommandID(GuidList.guidTWToolbarCmdSet, i); OleMenuCommand mc = new OleMenuCommand(new EventHandler(OnMCItemClicked), cmdID); mc.BeforeQueryStatus += new EventHandler(OnMCItemQueryStatus); mcs.AddCommand(mc); // The first item is, by default, checked. if (PkgCmdIDList.cmdidMCItem1 == i) { mc.Checked = true; this.currentMCCommand = i; } }
At the end of the TWToolbarPackage class, right after the MenuItemCallback method, add a method to mark the selected command as checked.
private void OnMCItemQueryStatus(object sender, EventArgs e) { OleMenuCommand mc = sender as OleMenuCommand; if (null != mc) { mc.Checked = (mc.CommandID.ID == this.currentMCCommand); } }
After the OnMCItemQueryStatus method, add an event handler for when the user selects a command on the menu controller:
private void OnMCItemClicked(object sender, EventArgs e) { OleMenuCommand mc = sender as OleMenuCommand; if (null != mc) { string selection; switch (mc.CommandID.ID) { case PkgCmdIDList.cmdidMCItem1: selection = "Menu controller Item 1"; break; case PkgCmdIDList.cmdidMCItem2: selection = "Menu controller Item 2"; break; case PkgCmdIDList.cmdidMCItem3: selection = "Menu controller Item 3"; break; default: selection = "Unknown command"; break; } this.currentMCCommand = mc.CommandID.ID; IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell)); Guid clsid = Guid.Empty; int result; uiShell.ShowMessageBox( 0, ref clsid, "Test Tool Window Toolbar Package", string.Format(CultureInfo.CurrentCulture, "You selected {0}", selection), string.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); } }
On the Build menu, click Build Solution to build the solution. Correct any errors that occur.
Testing the Menu Controller
To test the menu controller
Press F5 to open an instance of the experimental Visual Studio.
On the View menu, point to Other Windows, and then click Test Tool Window.
The menu controller appears in the toolbar in the tool window and displays "MC Item 1".
Click the menu controller button to the left of the little down arrow.
A dialog box appears and displays the message "Selected Menu controller Item 1". Note that the message corresponds to the text on the menu controller button.
Click the drop-down arrow on the menu controller to display three items, the first of which is selected with a highlight box around its icon. Click MC Item 3.
A dialog box appears and displays the message "Selected Menu controller Item 3". Note that the menu controller button now displays "MC Item 3".
On the menu controller, click the MC Item 3 button.
A dialog box appears and displays the message "Selecting Menu controller Item 3". This demonstrates that the menu controller has been modified to show the last-used command as the default.
Click the drop-down arrow on the menu controller to display the options. Notice that the new default, MC Item 3, now is selected.
See Also
Tasks
Walkthrough: Adding a Toolbar to a Tool Window (C#)
Walkthrough: Adding a Toolbar to the IDE