Custom User Interface (Source Control VSPackage)
This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, use the version selector at the top left. We recommend upgrading to Visual Studio 2019. Download it here
A VSPackage declares its menu items and their default states through the Visual Studio Command Table (.vsct) file. The Visual Studio integrated development environment (IDE) displays the menu items in their default states until the VSPackage is loaded. Subsequently, the QueryStatus method is called to enable or disable menu items.
A VSPackage can set a registry key so the VSPackage can be automatically loaded depending on a command user interface (UI) context, although typically a source control VSPackage should load on demand instead of just switching to a particular UI context. For more information about the AutoLoadPackages registry key, see Managing VSPackages.
A source control package is implemented as a VSPackage and does not use any UI from Visual Studio. Each source control VSPackage must specify its own UI elements such as menu items, menu groups, tool windows, toolbars, and any required UI for setting options specific to the source control VSPackage. These UI elements can be enabled statically or dynamically. Static UI elements are defined in a .vsct file and are displayed whether the VSPackage is loaded or not. Dynamic UI elements may be visible depending on a particular command UI context, such as vsContextNoSolution, or as the result of a call to the QueryStatus method. The visibility of dynamic UI elements complies with the strategy for delayed loading of VSPackages.
UI Constraints on Source Control VSPackages
Because the source control VSPackage cannot be removed from the IDE after it is loaded, the VSPackage must be able to enter an inactive state. When a VSPackage receives notification that it is no longer active, the VSPackage disables its UI and ignores any external IDE interaction. The VSPackage's implementation of the QueryStatus method should hide commands when the VSPackage is not active.
The source control VSPackage may have subscribed to various IDE events, which are implemented by the IVsSolutionEvents3, IVsTrackProjectDocumentsEvents2, and so on. Also, the VSPackage may have implemented registry-enabled callback interfaces, such as the IVsSolutionPersistence. These must all be ignored when inactive.
The following list shows the interfaces affected by the active state of a source control VSPackage:
Track Project Documents events.
Solution persistence interfaces. When inactive, packages should not write to .sln and .suo files.
When the Visual Studio IDE starts, Visual Studio sets the command UI context to the ID of the current default source control VSPackage ID. This causes the static UI of the active source control VSPackage to appear in the IDE without actually loading the VSPackage. Visual Studio pauses for the VSPackage to register with Visual Studio through the IVsRegisterScciProvider before it makes any calls to the VSPackage.
The following table describes specific details about how the Visual Studio IDE hides different UI items.
|Menus and toolbars||The source control package must set the initial menu and toolbar visibility states to the source control package ID in the VisibilityConstraints section of the .vsct file. This enables the Visual Studio IDE to set the state of the menu items appropriately without loading the VSPackage and calling an implementation of the QueryStatus method.|
|Tool windows||The source control VSPackage hides any tool windows it owns when it is made inactive.|
|Source control VSPackage-specific options pages||The registry key HKLM\SOFTWARE\Microsoft\VisualStudio\X.Y\ToolsOptionsPages\VisibilityCmdUIContexts lets a VSPackage set the contexts in which it requires its options pages to be displayed. A registry entry under this key would have to be created by using the service ID (SID) of the source control service and assigning it a DWORD value of 1. Whenever a UI event occurs in a context the source control VSPackage is registered with, the VSPackage will be called if it is active.|