自定义用户界面(源代码管理 VSPackage)

VSPackage 通过 Visual Studio 命令表 (.vsct) 文件声明其菜单项及其默认状态。 在加载 VSPackage 之前,Visual Studio 集成开发环境(IDE)以默认状态显示菜单项。 随后, QueryStatus 调用该方法以启用或禁用菜单项。

VSPackage 可以设置注册表项,以便可以根据命令用户界面(UI)上下文自动加载 VSPackage,尽管通常源代码管理 VSPackage 应按需加载,而不只是切换到特定的 UI 上下文。 有关 AutoLoadPackages 注册表项的详细信息,请参阅管理 VSPackage。

VSPackage UI

源代码管理包作为 VSPackage 实现,不使用 Visual Studio 中的任何 UI。 每个源代码管理 VSPackage 必须指定其自己的 UI 元素,例如菜单项、菜单组、工具窗口、工具栏以及设置特定于源代码管理 VSPackage 的选项所需的任何 UI。 可以静态或动态启用这些 UI 元素。 静态 UI 元素在 .vsct 文件中定义,并且是否加载 VSPackage 时显示。 动态 UI 元素可能根据特定的命令 UI 上下文(例如 vsContextNoSolution)或调用方法的结果 QueryStatus 可见。 动态 UI 元素的可见性符合 VSPackage 加载延迟的策略。

源代码管理 VSPackage 的 UI 约束

由于加载源代码管理 VSPackage 后无法从 IDE 中删除,因此 VSPackage 必须能够进入非活动状态。 当 VSPackage 收到不再处于活动状态的通知时,VSPackage 将禁用其 UI 并忽略任何外部 IDE 交互。 当 VSPackage 不处于活动状态时,VSPackage 的方法的实现 QueryStatus 应隐藏命令。

每个源代码管理 VSPackage 都必须实现 IVsSccProvider 接口。 接口上的两种方法, SetActive 并且 SetInactive必须由 VSPackage 实现。

源代码管理 VSPackage 可能已订阅各种 IDE 事件,这些事件由 IVsSolutionEvents3IVsTrackProjectDocumentsEvents2 实现,等等。 此外,VSPackage 可能已实现已启用注册表的回调接口,例如 IVsSolutionPersistence。 当非活动时,必须忽略这些接口。

以下列表显示受源代码管理 VSPackage 活动状态影响的接口:

  • 跟踪项目文档事件。

  • 解决方案事件。

  • 解决方案持久性接口。 如果处于非活动状态,则包不应写入 .sln.suo 文件。

  • 属性扩展器。

    当源代码管理 VSPackage 处于非活动状态时,不会调用必需IVsQueryEditQuerySave2IVsSccManager2接口以及与源代码管理关联的任何可选接口。

    Visual Studio IDE 启动时,Visual Studio 会将命令 UI 上下文设置为当前默认源代码管理 VSPackage ID 的 ID。 这会导致活动源代码管理 VSPackage 的静态 UI 显示在 IDE 中,而不会实际加载 VSPackage。 在对 VSPackage 进行任何调用之前,Visual Studio 会暂停 VSPackage 以向 Visual Studio IVsRegisterScciProvider 注册。

    下表介绍了有关 Visual Studio IDE 如何隐藏不同 UI 项的特定详细信息。

UI 项 说明
菜单和工具栏 源代码管理包必须将初始菜单和工具栏可见性状态设置为 .vsct 文件的 VisibilityConstraints 部分中的源代码管理包 ID 这使 Visual Studio IDE 可以适当地设置菜单项的状态,而无需加载 VSPackage 并调用方法的 QueryStatus 实现。
工具窗口 源代码管理 VSPackage 隐藏它在处于非活动状态时拥有的任何工具窗口。
源代码管理 VSPackage 特定的选项页 注册表项 HKLM\SOFTWARE\Microsoft\VisualStudio\X.Y\ToolsOptionsPages\VisibilityCmdUIContexts 允许 VSPackage 设置需要显示其选项页的上下文。 必须使用源代码管理服务的服务 ID(SID)为其分配 DWORD 值 1 来创建此密钥下的注册表项。 每当在源代码管理 VSPackage 注册到的上下文中发生 UI 事件时,如果 VSPackage 处于活动状态,将调用 VSPackage。