将菜单控制器添加到工具栏

本演练基于 “向工具窗口 添加工具栏”演练,并演示如何向工具窗口工具栏添加菜单控制器。 此处显示的步骤也可以应用于在“添加工具栏”演练中创建的 工具栏

菜单控制器是拆分控件。 菜单控制器的左侧显示最后一个使用的命令,可以通过单击它来运行它。 菜单控制器的右侧是一个箭头,单击时会打开其他命令的列表。 单击列表中的命令时,该命令将运行,并替换菜单控制器左侧的命令。 这样,菜单控制器将像命令按钮一样运行,该按钮始终显示列表中的最后一个使用命令。

菜单控制器可以在菜单上显示,但它们最常用于工具栏。

创建菜单控制器

  1. 按照“向工具窗口添加工具栏”中所述的过程操作,创建具有工具栏的工具窗口。

  2. TWTestCommandPackage.vsct 中,转到“符号”部分。 在名为 guidTWTestCommandPackageCmdSet 的 GuidSymbol 元素中,声明菜单控制器、菜单控制器组和三个菜单项。

    <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" />
    
  3. 在“菜单”部分中,在最后一个菜单项之后,将菜单控制器定义为菜单。

    <Menu guid="guidTWTestCommandPackageCmdSet" id="TestMenuController" priority="0x0100" type="MenuController">
        <Parent guid="guidTWTestCommandPackageCmdSet" id="TWToolbarGroup" />
        <CommandFlag>IconAndText</CommandFlag>
        <CommandFlag>TextChanges</CommandFlag>
        <CommandFlag>TextIsAnchorCommand</CommandFlag>
        <Strings>
            <ButtonText>Test Menu Controller</ButtonText>
            <CommandName>Test Menu Controller</CommandName>
        </Strings>
    </Menu>
    

    TextChanges必须包含和TextIsAnchorCommand标志才能让菜单控制器反映最后一个选定的命令。

  4. 在“组”部分中,在最后一个组项之后,添加菜单控制器组。

    <Group guid="guidTWTestCommandPackageCmdSet" id="TestMenuControllerGroup" priority="0x000">
        <Parent guid="guidTWTestCommandPackageCmdSet" id="TestMenuController" />
    </Group>
    

    通过将菜单控制器设置为父级,此组中放置的任何命令都将显示在菜单控制器中。 省略该 priority 属性,该属性将其设置为默认值 0,因为它是菜单控制器上唯一的组。

  5. 在“按钮”部分中,在最后一个按钮项之后,为每个菜单项添加一个 Button 元素。

    <Button guid="guidTWTestCommandPackageCmdSet" id="cmdidMCItem1" priority="0x0000" type="Button">
        <Parent guid="guidTWTestCommandPackageCmdSet" id="TestMenuControllerGroup" />
        <Icon guid="guidImages" id="bmpPic1" />
        <CommandFlag>IconAndText</CommandFlag>
        <Strings>
            <ButtonText>MC Item 1</ButtonText>
            <CommandName>MC Item 1</CommandName>
        </Strings>
    </Button>
    <Button guid="guidTWTestCommandPackageCmdSet" id="cmdidMCItem2" priority="0x0100" type="Button">
        <Parent guid="guidTWTestCommandPackageCmdSet" id="TestMenuControllerGroup" />
        <Icon guid="guidImages" id="bmpPic2" />
        <CommandFlag>IconAndText</CommandFlag>
        <Strings>
            <ButtonText>MC Item 2</ButtonText>
            <CommandName>MC Item 2</CommandName>
        </Strings>
    </Button>
    <Button guid="guidTWTestCommandPackageCmdSet" id="cmdidMCItem3" priority="0x0200" type="Button">
        <Parent guid="guidTWTestCommandPackageCmdSet" id="TestMenuControllerGroup" />
        <Icon guid="guidImages" id="bmpPicSearch" />
        <CommandFlag>IconAndText</CommandFlag>
        <Strings>
            <ButtonText>MC Item 3</ButtonText>
            <CommandName>MC Item 3</CommandName>
        </Strings>
    </Button>
    
  6. 此时,可以查看菜单控制器。 生成项目并启动调试。 应会看到实验实例。

    1. “视图”/“其他 Windows ”菜单上,打开 测试 ToolWindow

    2. 菜单控制器显示在工具窗口中的工具栏上。

    3. 单击菜单控制器右侧的箭头以查看三个可能的命令。

      请注意,单击命令时,菜单控制器的标题将更改为显示该命令。 在下一部分中,我们将添加代码以激活这些命令。

实现菜单控制器命令

  1. TWTestCommandPackageGuids.cs 中,在现有命令 ID 后面为三个菜单项添加命令 ID。

    public const int cmdidMCItem1 = 0x130;
    public const int cmdidMCItem2 = 0x131;
    public const int cmdidMCItem3 = 0x132;
    
  2. TWTestCommand.cs 中,在类顶部 TWTestCommand 添加以下代码。

    private int currentMCCommand; // The currently selected menu controller command
    
  3. 在 TWTestCommand 构造函数中,在对方法的最后一次调用 AddCommand 之后,添加代码以通过相同的处理程序路由每个命令的事件。

    for (int i = TWTestCommandPackageGuids.cmdidMCItem1; i <=
        TWTestCommandPackageGuids.cmdidMCItem3; i++)
    {
        CommandID cmdID = new
        CommandID(new Guid(TWTestCommandPackageGuids.guidTWTestCommandPackageCmdSet), i);
        OleMenuCommand mc = new OleMenuCommand(new
          EventHandler(OnMCItemClicked), cmdID);
        mc.BeforeQueryStatus += new EventHandler(OnMCItemQueryStatus);
        commandService.AddCommand(mc);
        // The first item is, by default, checked. 
        if (TWTestCommandPackageGuids.cmdidMCItem1 == i)
        {
            mc.Checked = true;
            this.currentMCCommand = i;
        }
    }
    
  4. 将事件处理程序添加到 TWTestCommand 类,将所选命令标记为检查。

    private void OnMCItemQueryStatus(object sender, EventArgs e)
    {
        OleMenuCommand mc = sender as OleMenuCommand;
        if (null != mc)
        {
            mc.Checked = (mc.CommandID.ID == this.currentMCCommand);
        }
    }
    
  5. 添加一个事件处理程序,当用户在菜单控制器上选择命令时显示 MessageBox:

    private void OnMCItemClicked(object sender, EventArgs e)
    {
        OleMenuCommand mc = sender as OleMenuCommand;
        if (null != mc)
        {
            string selection;
            switch (mc.CommandID.ID)
            {
                case c.cmdidMCItem1:
                    selection = "Menu controller Item 1";
                    break;
    
                case TWTestCommandPackageGuids.cmdidMCItem2:
                    selection = "Menu controller Item 2";
                    break;
    
                case TWTestCommandPackageGuids.cmdidMCItem3:
                    selection = "Menu controller Item 3";
                    break;
    
                default:
                    selection = "Unknown command";
                    break;
            }
            this.currentMCCommand = mc.CommandID.ID;
    
            IVsUIShell uiShell =
              (IVsUIShell) ServiceProvider.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);
        }
    }
    

测试菜单控制器

  1. 生成项目并启动调试。 应会看到实验实例。

  2. “视图”/“其他 Windows”菜单上打开测试 ToolWindow

    菜单控制器显示在工具窗口中的工具栏中,并显示 MC 项 1

  3. 单击箭头左侧的菜单控制器按钮。

    应会看到三个项目,其中第一项处于选中状态,并在其图标周围有一个突出显示框。 单击 MC 项目 3

    此时会显示一个对话框,其中包含“你选择的菜单控制器项 3”消息。 请注意,消息对应于菜单控制器按钮上的文本。 菜单控制器按钮现在显示 MC 项 3