How to: Create Menus, SubMenus, and Shortcut Menus
To add a menu to the Visual Studio integrated development environment (IDE), a VSPackage must use the Visual Studio SDK architecture for command-group menus. A command-group menu enables the sharing of commands by components and the IDE. For more information about command-group menus, see How VSPackages Add User Interface Elements to the IDE.
In VSPackages, menus are defined in the Menus section of a .vsct file. A .vsct file defines menus, toolbars, groups, and commands. A command is what a user clicks to perform a function. A group is a container for commands. A menu is a container for groups. To create a basic menu, you must create a menu, a command group, and at least one command.
There are three basic ways that a menu can appear in Visual Studio:
As a menu on the main menu bar.
As a submenu of another menu.
As a shortcut menu (typically displayed by a right-click).
This topic shows how to create each kind of menu. The following walkthroughs also show how to do this:
To create a menu, submenu, or shortcut menu
In your project, double-click the .vsct file to open it in the editor.
If your project does not have a .vsct file, add one. If you are creating a package by using the Visual Studio Package Template, select Menu Command; doing this will generate a .vsct file.
In the Symbols section, find the GuidSymbol element that contains the groups and commands.
Create an IDSymbol element for each menu, group, or command that you want to add, as shown in the following example.
<GuidSymbol name="guidButtonGroupCmdSet" value="{f69209e9-975a-4543-821d-1f4a2c52d737}"> <IDSymbol name="MyMenuGroup" value="0x1020" /> <IDSymbol name="cmdidMyCommand" value="0x0100" /> </GuidSymbol>
The name attributes of the GuidSymbol and IDSymbol elements provide the GUID:ID pair for each new menu, group, or command. The GUID represents a command set that is defined for your VSPackage. You can define multiple command sets. Each GUID:ID pair must be unique.
Define the new menu in the Menus section, as follows:
Set the guid and id fields to match the GUID:ID of the new menu.
Set the priority attribute.
The priority attribute is used by the .vsct file to determine the location of the menu among the other objects in the parent group.
Menus that have lower-priority values are displayed before menus that have higher-priority values. Duplicate priority values are permitted, but the relative position of menus that have equal priority is determined by the order in which VSPackages are processed at run time, and that order cannot be predetermined. Omitting the priority attribute sets its value to 0.
Do not set a priority for a shortcut menu, because its placement is determined by the code that calls it.
For menus and submenus, set the type attribute to Menu, which describes a typical menu. For shortcut menus, set the type attribute to Context.
For descriptions of other valid menu types, such as toolbars and menu controllers, see Menu Element.
In the menu definition, create a Strings section that contains a ButtonText element to contain the name of the menu as it appears in the IDE, and a CommandName element to contain the name of the command that is used to access the menu in the Command window.
If the button text string includes the '&' character, the user can open the menu by pressing ALT plus the character that immediately follows the '&'.
Add command flags, as appropriate, to change the appearance and behavior of the menu. To do this, add a CommandFlag element in the menu definition. For more information, see Command Flag Element.
Set the parent of the menu. For a standard menu or submenu, do this in one of the following ways, depending on your design:
In the Menu element, create a Parent element and set its guid and id fields to the GUID:ID of the group that will host the menu, also known as the primary parent group. The parent group can be a group that you created in the Symbols section, a group from another package, or a group from the IDE. For example, to add your menu to the top-level menu bar of the IDE, near the Tools menu, set the parent to guidSHLMainMenu:IDG_VS_MM_TOOLSADDINS.
The following example shows a menu that will appear on the Visual Studio menu bar.
<Menu guid="guidTopLevelMenuCmdSet" id="TopLevelMenu" priority="0x700" type="Menu"> <Parent guid="guidSHLMainMenu" id="IDG_VS_MM_TOOLSADDINS" /> <Strings> <ButtonText>TestMenu</ButtonText> <CommandName>TestMenu</CommandName> </Strings> </Menu>
You may omit the Parent element if the menu is to be positioned by using command placement. Create a CommandPlacements section before the Symbols section, and add a CommandPlacement element that has the GUID:ID of the menu, a priority, and a parent, as shown in the following example.
<CommandPlacements> <CommandPlacement guid="guidButtonGroupCmdSet" id="cmdidMyCommand" priority="0x105"> <Parent guid="guidButtonGroupCmdSet" id="MyMenuGroup" /> </CommandPlacement> </CommandPlacements>
Creating multiple command placements that have the same GUID:ID and have different parents causes a menu to appear in multiple locations. For more information, see CommandPlacements Element.
A standard menu must have a group on the Visual Studio menu bar as its parent. For a submenu, the parent must be a group on another menu (or on a toolbar or other menu type). For a menu or submenu to be displayed, it must host a group that contains at least one active command, or have the AlwaysCreate command flag set.
Shortcut menus do not have parents or command placements. Instead, they must be activated in code. Typically, a shortcut menu is activated in response to a right-click on a control surface. The following example defines a shortcut menu.
<Menu guid="guidButtonGroupCmdSet" id="ShortcutMenu" type="Context"> <Strings> <ButtonText>Shortcut Menu</ButtonText> <CommandName>ShortcutMenu</CommandName> </Strings> </Menu>
In the Groups section, create a Group element to contain the commands that are to appear on your menu. The Symbols section must include an entry that has the same GUID:ID as the new Group element.
Set the priority of the group so that it will appear where you want it on your menu.
The boundaries of each group on the menu will appear as horizontal lines.
Set the parent for this new group to the GUID:ID of the menu that you created. Doing this puts the group of commands on the menu.
The group in the following example appears on the top-level menu that was shown in an earlier example.
<Group guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" priority="0x0600"> <Parent guid="guidTopLevelMenuCmdSet" id="TopLevelMenu"/> </Group>
Menus can contain both commands and submenus. A submenu (sometimes referred to as a cascading menu) is just a menu, but it is one that is added to another menu's group and is exposed only when that other menu is invoked. By putting the menu that is shown in the following example in a group in the top-level menu, it becomes a submenu.
<Menu guid="guidTopLevelMenuCmdSet" id="SubMenu" priority="0x0100" type="Menu"> <Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup"/> <Strings> <ButtonText>Sub Menu</ButtonText> <CommandName>Sub Menu</CommandName> </Strings> </Menu>
Add commands to the menu by creating command entries in the Buttons section and setting the parent of each to the GUID:ID of your group. Each Button element must have a GUID:ID that corresponds to an entry in the Symbols section.
Use the priority attribute of each button entry to specify the order in which the commands appear in the group.
The following example defines a command that will appear on the top-level menu.
<Button guid="guidTopLevelMenuCmdSet" id="cmdidTestCommand" priority="0x0100" type="Button"> <Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" /> <Icon guid="guidImages" id="bmpPic1" /> <Strings> <CommandName>cmdidTestCommand</CommandName> <ButtonText>Test Command</ButtonText> </Strings> </Button>
For more information about buttons and menu items, see Button Element.
For information about how to implement menu commands in code, see How to: Create and Handle Commands in VSPackages (C#) or the walkthroughs that are mentioned earlier in this topic.
To activate a shortcut menu
Obtain the GUID:ID of the shortcut menu. By default, the package template creates a GuidList class in a PkgCmdID.cs file to hold the GUID of the command set. The template also creates a PkgCmdIdList class in a PkgCmdId.cs file to hold the integer ID values of commands that are declared in the template. Shortcut menus and any additional commands must be declared after the template is finished. The following example shows these declarations.
static class PkgCmdIDList { public const uint cmdidColorChange = 0x101; public const int ColorMenu = 0x1000; public const int cmdidRed = 0x102; public const int cmdidYellow = 0x103; public const int cmdidBlue = 0x104; };
This step can be omitted if the GUID and ID values will be used directly. However, we recommend that you set the values here for readability.
Attach to an event handler. Typically, shortcut menus attach to the right-click of a control surface, as shown in the following example.
private void MyToolWindow_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { OleMenuCommandService mcs = this._parent.mcs; if (null != mcs) { CommandID menuID = new CommandID( GuidList.guidTWShortcutMenuCmdSet, PkgCmdIDList.ColorMenu); Point p = this.PointToScreen(e.GetPosition(this)); mcs.ShowContextMenu(menuID, (int)p.X, (int)p.Y); } }
The PointToScreen method converts the click position, which is relative to the control, to a screen position. The ShowContextMenu method displays the shortcut menu.
The file that contains the event handler must include the System.ComponentModel.Design namespace to access the OleMenuCommandService class, and the Microsoft.VisualStudio.Shell namespace to access the IMenuCommandService interface.
using Microsoft.VisualStudio.Shell; using System.ComponentModel.Design;
See Also
Tasks
How to: Create and Handle Commands in VSPackages (C#)