本演练将快捷菜单放在工具窗口中。 快捷菜单是当用户右键单击按钮、文本框或窗口背景时显示的菜单。 快捷菜单上的命令的行为与其他菜单或工具栏上的命令相同。 若要支持快捷菜单,请在 .vsct 文件中指定它,并在响应鼠标右键单击时显示它。
工具窗口由从中 ToolWindowPane继承的自定义工具窗口类中的 WPF 用户控件组成。
本演练演示如何通过声明 .vsct 文件中的菜单项,然后使用托管包框架在定义工具窗口的类中实现快捷菜单作为 Visual Studio 菜单。 此方法有助于访问 Visual Studio 命令、UI 元素和自动化对象模型。
或者,如果快捷菜单无法访问 Visual Studio 功能,则可以在用户控件中使用 ContextMenu XAML 元素的属性。 有关详细信息,请参阅 ContextMenu。
创建工具窗口快捷菜单包
- 创建名为
TWShortcutMenu
“ShortcutMenu”的工具窗口模板并将其添加到它的 VSIX 项目。 有关创建工具窗口的详细信息,请参阅 使用工具窗口创建扩展。
指定快捷菜单
此演练中显示的快捷菜单允许用户从用于填充工具窗口背景的颜色列表中选择。
在 ShortcutMenuPackage.vsct 中,在名为 guidShortcutMenuPackageCmdSet 的 GuidSymbol 元素中找到,并声明快捷菜单、快捷菜单组和菜单选项。 GuidSymbol 元素现在应如下所示:
<GuidSymbol name="guidShortcutMenuPackageCmdSet" value="{00000000-0000-0000-0000-0000}"> // your GUID here <IDSymbol name="ShortcutMenuCommandId" value="0x0100" /> <IDSymbol name="ColorMenu" value="0x1000"/> <IDSymbol name="ColorGroup" value="0x1100"/> <IDSymbol name="cmdidRed" value="0x102"/> <IDSymbol name="cmdidYellow" value="0x103"/> <IDSymbol name="cmdidBlue" value="0x104"/> </GuidSymbol>
就在 Buttons 元素之前,创建一个 Menu 元素,然后在其中定义快捷菜单。
<Menus> <Menu guid="guidShortcutMenuPackageCmdSet" id="ColorMenu" type="Context"> <Strings> <ButtonText>Color change</ButtonText> <CommandName>ColorChange</CommandName> </Strings> </Menu> </Menus>
快捷菜单没有父菜单,因为它不是菜单或工具栏的一部分。
使用包含快捷菜单项的 Group 元素创建 Groups 元素,并将该组与快捷菜单相关联。
<Groups> <Group guid="guidShortcutMenuPackageCmdSet" id="ColorGroup"> <Parent guid="guidShortcutMenuPackageCmdSet" id="ColorMenu"/> </Group> </Groups>
在 Buttons 元素中,定义将在快捷菜单上显示的单个命令。 Buttons 元素应如下所示:
<Buttons> <Button guid="guidShortcutMenuPackageCmdSet" id="ShortcutMenuCommandId" priority="0x0100" type="Button"> <Parent guid="guidSHLMainMenu" id="IDG_VS_WNDO_OTRWNDWS1"/> <Icon guid="guidImages" id="bmpPic1" /> <Strings> <ButtonText>ShortcutMenu</ButtonText> </Strings> </Button> <Button guid="guidShortcutMenuPackageCmdSet" id="cmdidRed" priority="1" type="Button"> <Parent guid="guidShortcutMenuPackageCmdSet" id="ColorGroup" /> <Strings> <ButtonText>Red</ButtonText> </Strings> </Button> <Button guid="guidShortcutMenuPackageCmdSet" id="cmdidYellow" priority="3" type="Button"> <Parent guid="guidShortcutMenuPackageCmdSet" id="ColorGroup" /> <Strings> <ButtonText>Yellow</ButtonText> </Strings> </Button> <Button guid="guidShortcutMenuPackageCmdSet" id="cmdidBlue" priority="5" type="Button"> <Parent guid="guidShortcutMenuPackageCmdSet" id="ColorGroup" /> <Strings> <ButtonText>Blue</ButtonText> </Strings> </Button> </Buttons>
在 ShortcutMenuCommand.cs 中,添加命令集 GUID、快捷菜单和菜单项的定义。
public const string guidShortcutMenuPackageCmdSet = "00000000-0000-0000-0000-00000000"; // your GUID will differ public const int ColorMenu = 0x1000; public const int cmdidRed = 0x102; public const int cmdidYellow = 0x103; public const int cmdidBlue = 0x104;
这些命令 ID 与 ShortcutMenuPackage.vsct 文件的 Symbols 节中定义的命令 ID 相同。 此处不包含上下文组,因为它仅在 .vsct 文件中是必需的。
实现快捷菜单
本部分实现快捷菜单及其命令。
在 ShortcutMenu.cs 中,工具窗口可以获取菜单命令服务,但它包含的控件不能。 以下步骤演示如何使菜单命令服务可供用户控件使用。
在 ShortcutMenu.cs 中,添加以下 using 指令:
using Microsoft.VisualStudio.Shell; using System.ComponentModel.Design;
重写工具窗口的 Initialize() 方法以获取菜单命令服务并添加控件,并将菜单命令服务传递给构造函数:
protected override void Initialize() { var commandService = (OleMenuCommandService)GetService(typeof(IMenuCommandService)); Content = new ShortcutMenuControl(commandService); }
在 ShortcutMenu 工具窗口构造函数中,删除添加控件的行。 构造函数现在应如下所示:
public ShortcutMenu() : base(null) { this.Caption = "ShortcutMenu"; this.BitmapResourceID = 301; this.BitmapIndex = 1; }
在 ShortcutMenuControl.xaml.cs 中,为菜单命令服务添加专用字段,并更改控件构造函数以执行菜单命令服务。 然后使用菜单命令服务添加上下文菜单命令。 ShortcutMenuControl 构造函数现在应类似于以下代码。 稍后将定义命令处理程序。
public ShortcutMenuControl(OleMenuCommandService service) { this.InitializeComponent(); commandService = service; if (null !=commandService) { // Create an alias for the command set guid. Guid guid = new Guid(ShortcutMenuCommand.guidShortcutMenuPackageCmdSet); // Create the command IDs. var red = new CommandID(guid, ShortcutMenuCommand.cmdidRed); var yellow = new CommandID(guid, ShortcutMenuCommand.cmdidYellow); var blue = new CommandID(guid, ShortcutMenuCommand.cmdidBlue); // Add a command for each command ID. commandService.AddCommand(new MenuCommand(ChangeColor, red)); commandService.AddCommand(new MenuCommand(ChangeColor, yellow)); commandService.AddCommand(new MenuCommand(ChangeColor, blue)); } }
在 ShortcutMenuControl.xaml 中,将事件 MouseRightButtonDown 添加到顶级 UserControl 元素。 XAML 文件现在应如下所示:
<UserControl x:Class="TWShortcutMenu.ShortcutMenuControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" Background="{DynamicResource VsBrush.Window}" Foreground="{DynamicResource VsBrush.WindowText}" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Name="MyToolWindow" MouseRightButtonDown="MyToolWindow_MouseRightButtonDown"> <Grid> <StackPanel Orientation="Vertical"> <TextBlock Margin="10" HorizontalAlignment="Center">ShortcutMenu</TextBlock> </StackPanel> </Grid> </UserControl>
在 ShortcutMenuControl.xaml.cs 中,为事件处理程序添加存根。
private void MyToolWindow_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { . . . }
将以下 using 指令添加到同一文件:
using Microsoft.VisualStudio.Shell; using System.ComponentModel.Design; using System; using System.Windows.Input; using System.Windows.Media;
MyToolWindowMouseRightButtonDown
按如下所示实现事件。private void MyToolWindow_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { if (null != commandService) { CommandID menuID = new CommandID( new Guid(ShortcutMenuCommand.guidShortcutMenuPackageCmdSet), ShortcutMenuCommand.ColorMenu); Point p = this.PointToScreen(e.GetPosition(this)); commandService.ShowContextMenu(menuID, (int)p.X, (int)p.Y); } }
这将为快捷菜单创建一个 CommandID 对象,标识鼠标单击的位置,并使用 ShowContextMenu 该方法打开该位置的快捷菜单。
实现命令处理程序。
private void ChangeColor(object sender, EventArgs e) { var mc = sender as MenuCommand; switch (mc.CommandID.ID) { case ShortcutMenuCommand.cmdidRed: MyToolWindow.Background = Brushes.Red; break; case ShortcutMenuCommand.cmdidYellow: MyToolWindow.Background = Brushes.Yellow; break; case ShortcutMenuCommand.cmdidBlue: MyToolWindow.Background = Brushes.Blue; break; } }
在这种情况下,只有一种方法通过相应地标识 CommandID 和设置背景色来处理所有菜单项的事件。 如果菜单项包含不相关的命令,则会为每个命令创建单独的事件处理程序。
测试工具窗口功能
生成项目并启动调试。 这将显示实验实例。
在实验实例中,单击“ 视图”/“其他 Windows”,然后单击“ ShortcutMenu”。 执行此操作应显示工具窗口。
在工具窗口的正文中右键单击。 应显示具有颜色列表的快捷菜单。
单击快捷菜单上的颜色。 工具窗口背景色应更改为所选颜色。