使命令可用

将多个 VSPackage 添加到 Visual Studio 时,用户界面(UI)可能会因命令而过度拥挤。 你可以对包进行编程以帮助减少此问题,如下所示:

  • 对包进行编程,以便仅在用户需要它时才加载它。

  • 对包进行编程,以便仅在集成开发环境(IDE)的当前状态上下文中需要命令时才显示它们。

延迟加载

启用延迟加载的典型方法是设计 VSPackage,以便其命令显示在 UI 中,但在用户单击其中一个命令之前,包本身不会加载。 为此,请在 .vsct 文件中创建没有命令标志的命令。

以下示例显示了 .vsct 文件中菜单命令的定义。 这是选择模板中的“菜单命令”选项时 Visual Studio 包模板生成的命令

<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>

在此示例中,如果父组 MyMenuGroup是顶级菜单(如 “工具” 菜单)的子级,该命令将在该菜单上可见,但在用户单击命令之前,不会加载执行该命令的包。 但是,通过编程命令来实现 IOleCommandTarget 接口,可以在首次展开包含命令的菜单时加载包。

请注意,延迟加载也可能提高启动性能。

当前上下文和命令的可见性

可以根据 VSPackage 数据的当前状态或当前相关的操作对 VSPackage 命令进行编程,以便可见或隐藏。 可以启用 VSPackage 以设置其命令的状态,通常通过使用接口中方法IOleCommandTargetQueryStatus实现,但这需要加载 VSPackage,然后才能执行代码。 相反,我们建议你启用 IDE 来管理命令的可见性,而无需加载包。 为此,在 .vsct 文件中,将命令与一个或多个特殊 UI 上下文相关联。 这些 UI 上下文由称为命令上下文 GUID 的 GUID 标识。

Visual Studio 监视用户操作(例如加载项目或从编辑到生成)导致的更改。 发生更改时,会自动修改 IDE 的外观。 下表显示了 Visual Studio 监视的 IDE 更改的四个主要上下文。

上下文类型 说明
活动项目类型 对于大多数项目类型,此值 GUID 与实现项目的 VSPackage 的 GUID 相同。 但是,Visual C++ 项目使用项目类型 GUID 作为值。
活动窗口 通常,这是最后一个活动文档窗口,用于为键绑定建立当前 UI 上下文。 但是,它也可能是一个工具窗口,其键绑定表类似于内部 Web 浏览器。 对于多选项卡式文档窗口(如 HTML 编辑器),每个选项卡都有不同的命令上下文 GUID
活动语言服务 与当前显示在文本编辑器中的文件关联的语言服务。
活动工具窗口 打开并具有焦点的工具窗口。

第五个主要上下文区域是 IDE 的 UI 状态。 UI 上下文由活动命令上下文 GUID标识,如下所示:

这些 GUID 标记为活动或非活动状态,具体取决于 IDE 的当前状态。 多个 UI 上下文可以同时处于活动状态。

基于上下文隐藏和显示命令

可以在 IDE 中显示或隐藏包命令,而无需加载包本身。 为此,请使用 DefaultDisabledDefaultInvisible命令标志在包的 .vsct 文件中定义命令, DynamicVisibility 并将一个或多个 VisibilityItem 元素添加到 VisibilityConstraints 节。 当指定的命令上下文 GUID 变为活动状态时,将显示该命令而不加载包。

自定义上下文 GUID

如果尚未定义适当的命令上下文 GUID,则可以在 VSPackage 中定义一个 GUID,然后根据需要将其编程为活动或非活动状态,以控制命令的可见性。 使用服务 SVsShellMonitorSelection 可以:

  • 注册上下文 GUID(通过调用 GetCmdUIContextCookie 方法)。

  • 获取上下文 GUID 的状态(通过调用 IsCmdUIContextActive 方法)。

  • 打开和关闭上下文 GUID(通过调用 SetCmdUIContext 方法)。

    注意

    请确保 VSPackage 不会影响任何现有上下文 GUID 的状态,因为其他 VSPackage 可能依赖于它们。

示例

VSPackage 命令的以下示例演示了由命令上下文管理的命令的动态可见性,而无需加载 VSPackage。

该命令设置为在解决方案存在时启用和显示;也就是说,每当以下命令上下文 GUID 之一处于活动状态时:

在此示例中,请注意,每个命令标志都是单独的 命令标志 元素。

<Button guid="guidDynamicVisibilityCmdSet" id="cmdidMyCommand"
        priority="0x0100" type="Button">
  <Parent guid="guidDynamicVisibilityCmdSet" id="MyMenuGroup" />
  <Icon guid="guidImages" id="bmpPic1" />
  <CommandFlag>DefaultDisabled</CommandFlag>
  <CommandFlag>DefaultInvisible</CommandFlag>
  <CommandFlag>DynamicVisibility</CommandFlag>
  <Strings>
    <CommandName>cmdidMyCommand</CommandName>
    <ButtonText>My Command name</ButtonText>
  </Strings>
</Button>

另请注意,每个 UI 上下文都必须在单独的 VisibilityItem 元素中提供,如下所示。

<VisibilityConstraints>
  <VisibilityItem guid="guidDynamicVisibilityCmdSet"
                  id="cmdidMyCommand" context="UICONTEXT_EmptySolution" />
  <VisibilityItem guid="guidDynamicVisibilityCmdSet"
                      id="cmdidMyCommand" context="UICONTEXT_SolutionHasSingleProject" />
  <VisibilityItem guid="guidDynamicVisibilityCmdSet"
                  id="cmdidMyCommand" context="UICONTEXT_SolutionHasMultipleProjects" />
</VisibilityConstraints>