生成自定义工具窗口

自定义工具窗口是向 Visual Studio 添加复杂 UI 的绝佳选项。

工具窗口是 Visual Studio 中的核心 UI 概念,以下视频将演示如何添加自定义窗口。

工具窗口是一个窗口,可以像解决方案资源管理器、错误列表和其他已知工具窗口一样移动和停靠。 工具窗口由 Visual Studio 提供的外部外壳和自定义内部 UI 控件(通常是扩展提供的 XAML <usercontrol>)组成。

注意

若要使用工具窗口创建新扩展,请使用 VSIX 项目 w/Tool Window(社区) 模板创建新项目,并跳过此食谱的其余部分。 有关详细信息,请参阅入门。

将工具窗口添加到现有扩展需要 4 个简单的步骤:

  1. 创建工具窗口外部 shell 类。
  2. 将 XAML <usercontrol> 添加到工具窗口。
  3. 注册工具窗口。
  4. 创建用于显示工具窗口的命令。

让我们从步骤 1 开始。

创建工具窗口

BaseToolWindow<T>使用泛型基类时,系统会要求我们提供一些基本信息。 我们必须指定工具窗口的标题,创建并返回 XAML 用户控件,并设置 Visual Studio 用于创建窗口外壳的实际 ToolWindowPane 类。

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Community.VisualStudio.Toolkit;
using EnvDTE80;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Shell;

public class MyToolWindow : BaseToolWindow<MyToolWindow>
{
    public override string GetTitle(int toolWindowId) => "My Tool Window";

    public override Type PaneType => typeof(Pane);

    public override async Task<FrameworkElement> CreateAsync(int toolWindowId, CancellationToken cancellationToken)
    {
        await Task.Delay(2000); // Long running async task
        return new MyUserControl();
    }

    // Give this a new unique guid
    [Guid("d3b3ebd9-87d1-41cd-bf84-268d88953417")] 
    internal class Pane : ToolWindowPane
    {
        public Pane()
        {
            // Set an image icon for the tool window
            BitmapImageMoniker = KnownMonikers.StatusInformation;
        }
    }
}

必须从 CreateAsync(int, CancellationToken) 方法创建自定义用户控件的实例,然后在 Visual Studio 创建自定义用户控件时自动传递给工具窗口 shell。

但首先,必须创建用户控件。

添加 XAML 用户控件

它可以是任何 XAML 及其代码隐藏类,因此下面是包含单个按钮的 <usercontrol> 简单示例:

<UserControl x:Class="MyUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:toolkit="clr-namespace:Community.VisualStudio.Toolkit;assembly=Community.VisualStudio.Toolkit"
             mc:Ignorable="d"
             toolkit:Themes.UseVsTheme="True"
             d:DesignHeight="300" d:DesignWidth="300"
             Name="MyToolWindow">
    <Grid>
        <StackPanel Orientation="Vertical">
            <Label Margin="10" HorizontalAlignment="Center">My Window</Label>
            <Button Content="Click me!" Click="button1_Click" Width="120" Height="80" Name="button1"/>
        </StackPanel>
    </Grid>
</UserControl>

现在,我们有了返回自定义控件的工具窗口类。 下一步是向 Visual Studio 注册工具窗口。

注册工具窗口

注册工具窗口意味着我们告诉 Visual Studio 它是否存在以及如何实例化它。 我们使用特性从包类 [ProvideToolWindow] 执行此操作。

[ProvideToolWindow(typeof(MyToolWindow.Pane))]
public sealed class MyPackage : ToolkitPackage
{
     protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
     {
         this.RegisterToolWindows();
     }
}

注意

请注意,包类必须继承自 ToolkitPackage 或从 PackageAsyncPackage继承。

可以指定工具窗口应具有的样式以及默认情况下应显示的位置。 以下示例显示工具窗口应放置在链接样式中的解决方案资源管理器相同的停靠容器中。

[ProvideToolWindow(typeof(MyToolWindow.Pane), Style = VsDockStyle.Linked, Window = WindowGuids.SolutionExplorer)]

若要使工具窗口默认可见,可以使用该属性在不同的 UI 上下文 [ProvideToolWindowVisibility] 中指定其可见性。

[ProvideToolWindowVisibility(typeof(MyToolWindow.Pane), VSConstants.UICONTEXT.NoSolution_string)]

用于显示工具窗口的命令

这与任何其他命令相同,你可以看到如何在菜单和命令食谱中添加一个命令。

显示工具窗口的命令处理程序类将如下所示:

using Community.VisualStudio.Toolkit;
using Microsoft.VisualStudio.Shell;
using Task = System.Threading.Tasks.Task;

[Command(PackageIds.RunnerWindow)]
internal sealed class MyToolWindowCommand : BaseCommand<MyToolWindowCommand>
{
    protected override async Task ExecuteAsync(OleMenuCmdEventArgs e) =>
        await MyToolWindow.ShowAsync();
}

工具窗口的命令放置通常位于 视图 -> 主菜单中的其他 Windows 下。

这就可以了。 恭喜,现已创建自定义工具窗口。

获取源代码

可以在示例存储库中找到此配方的源代码。