title | description | date |
---|---|---|
Tool Windows reference |
A reference for extensibility tool windows |
2022-07-20 |
Tool windows are a way to add complex UI and interactions to Visual Studio. They typically provide a user-friendly way to interact with various APIs and features. For example, the Solution Explorer tool window provides a tree-based view of the current project/solution/folder and provides simple gestures for the opening, renaming, and creating of files.
Tool windows are single-instance, meaning that only one instance of the Tool Window can be open at a time. When a Tool Window is closed in the IDE, it is only visibly hidden, instead of being fully closed and disposed of like documents.
To get started, follow the create your first extension tutorial.
This guide is designed to cover the top user scenarios when working with Tool Windows:
- Create a tool window
- Add content to a tool window
- Create a command to show a tool window
- Control the visibility of a tool window
Creating a tool window with the new Extensibility Model is as simple as extending the base class Microsoft.VisualStudio.Extensibility.ToolWindows.ToolWindow
and adorning your class with the attribute Microsoft.VisualStudio.Extensibility.ToolWindows.ToolWindowAttribute
.
[ToolWindow]
public class MyToolWindow : ToolWindow
The attribute ToolWindowAttribute
has a few parameters that you should become familiar with:
Parameter | Type | Required | Description | Default Value |
---|---|---|---|---|
Placement | ToolWindowPlacement or String | No | The location in Visual Studio where the tool window should be opened the first time. If this value is a string it's expected to be a guid matching an old vsix-style tool window id. See more about ToolWindowPlacement. | ToolWindowPlacement.Floating |
DockDirection | Dock | No | The direction relative to the placement where the tool window should be docked when opened the first time. See more about Dock. | Dock.None |
AllowAutoCreation | Bool | No | Whether or not the tool window can be created automatically. Setting this to false means that tool windows that are open when Visual Studio is closed will not be automatically restored when Visual Studio is opened again. | true |
[ToolWindow(placement: ToolWindowPlacement.Floating, dockDirection: Dock.Right, allowAutoCreation: true)]
public class MyToolWindow : ToolWindow
{
public MyToolWindow(VisualStudioExtensibility extensibility)
: base(extensibility)
{
this.Title = "My Tool Window";
}
public override Task<IRemoteUserControl> GetContentAsync(CancellationToken cancellationToken)
{
// Create and return a RemoteUserControl
}
}
Because extensions in VisualStudio.Extensibility might be out-of-process from the IDE, we cannot directly use WPF as a presentation layer for content in Tool Windows. Instead, adding content to a tool window requires creating a RemoteUserControl and the corresponding data template for that control. While there are some simple examples below, we recommend reading the Remote UI documentation when adding tool window content.
[ToolWindow(ToolWindowPlacement.DocumentWell)]
public class MyToolWindow : ToolWindow
{
public MyToolWindow(VisualStudioExtensibility extensibility)
: base(extensibility)
{
this.Title = "My Tool Window";
}
public override async Task InitializeAsync(CancellationToken cancellationToken)
{
// Do any work here that is needed before creating the control.
}
public override Task<IRemoteUserControl> GetContentAsync(CancellationToken cancellationToken)
{
return Task.FromResult<IRemoteUserControl>(new MyToolWindowControl());
}
}
MyToolWindowControl.cs: (this is an example file name and should have the same name as the data template file)
internal class MyToolWindowControl : RemoteUserControl
{
public MyToolWindowControl()
: base(dataContext: null)
{
}
}
MyToolWindowControl.xaml (this is an example file name and should have the same name as the class that derives from RemoteUserControl)
<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vs="http://schemas.microsoft.com/visualstudio/extensibility/2022/xaml">
<Label></Label>
</DataTemplate>
See the Remote UI docs for more information on creating a RemoteUserControl
.
A common mechanism for showing a tool window is to add a command that, when invoked, shows the tool window by calling ShellExtensibility.ShowToolWindowAsync()
.
ShowToolWindowAsync()
has a boolean parameter, activate
:
- When
true
, the tool window will be both visible in the IDE and given focus. - When
false
, the tool window will be visible in the IDE, but may be visible only as a tab in a tab group if other tool windows are active.
[Command("ToolWindowExtension.MyToolWindowCommand", "My Tool Window", placement: CommandPlacement.ToolsMenu)]
[CommandIcon(KnownMonikers.ToolWindow, IconSettings.IconAndText)]
public class MyToolWindowCommand : Command
{
public MyToolWindowCommand(VisualStudioExtensibility extensibility, string id)
: base(extensibility, id)
{
}
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
await this.Extensibility.Shell().ShowToolWindowAsync<MyToolWindow>(activate: true, cancellationToken);
}
}
See the Commands docs to learn more about creating and using commands.
Another way of controlling the visibility of a tool window, besides using commands, is to use rule-based activation constraints. This allows tool windows to automatically be opened when certain conditions are met, and hidden again when those conditions are no longer applicable.
The attribute Microsoft.VisualStudio.Extensibility.ToolWindows.ToolWindowVisibleWhenAttribute
has a few parameters that you should become familiar with:
Parameter | Type | Required | Description |
---|---|---|---|
Expression | String | Yes | A boolean expression string which, when true, will mean the context is active and the tool window will be shown. |
TermNames | String[] | Yes | The names of the terms used in the expression. |
TermValues | String[] | Yes | The values of each term. The term values must be in the same order as term names array. |
// The tool window will be shown if the active document is a .cs file, and
// will be hidden if the active document is any any other type of file.
[ToolWindow]
[ToolWindowVisibleWhen("FileSelected",
new string[] { "FileSelected" },
new string[] { "ClientContext:Shell.ActiveSelectionFileName=.cs$" })]
public class MyToolWindow : ToolWindow
See Rule-based activation constraints for more information on valid term values.
Be sure to read about Remote UI works in the VisualStudio.Extensibility framework.
Tool window content is created using WPF, so refer to the WPF documentation for guidance.
See the ToolWindowExtension sample for a full example of creating an extension with a tool window.