Создание пользовательских окон инструментов

Пользовательские окна инструментов — это отличные варианты добавления сложного пользовательского интерфейса в Visual Studio.

Окно инструментов — это основная концепция пользовательского интерфейса в Visual Studio, а в следующем видео показано, как добавить настраиваемое окно.

Окно инструментов — это окно, которое можно перемещать и закреплять так же, как Обозреватель решений, список ошибок и другие известные окна инструментов. Окно инструментов состоит из внешней оболочки, предоставляемой Visual Studio, и пользовательского внутреннего элемента управления пользовательского интерфейса, который обычно представляет собой XAML <usercontrol>, предоставляемый расширением.

Примечание

Чтобы создать расширение с окном инструментов, создайте новый проект с помощью шаблона vsIX Project w/Tool Window (Community) и пропустите остальную часть этого рецепта. Дополнительные сведения см. в статье о начале работы .

Для добавления окна инструментов в существующее расширение требуется 4 простых шага.

  1. Создайте внешний класс оболочки окна инструментов.
  2. Добавьте XAML <usercontrol> в окно инструментов.
  3. Зарегистрируйте окно средства.
  4. Создайте команду для отображения окна инструментов.

Начнем с шага 1.

Создание окна средства

Используя универсальный базовый BaseToolWindow<T> класс, мы просим предоставить несколько основных элементов информации. Необходимо указать заголовок окна инструментов, создать и вернуть пользовательский элемент управления XAML и задать фактический ToolWindowPane класс, используемый Visual Studio для создания внешней оболочки окна.

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.

Но сначала необходимо создать элемент управления пользователем.

Добавление пользовательского элемента управления XAML

Это может быть любой XAML с его классом code-behind, поэтому ниже приведен простой пример <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 Package него.AsyncPackage

Можно указать, какой стиль должен иметь окно инструментов и где он должен отображаться по умолчанию. В следующем примере показано, что окно инструментов должно размещаться в том же контейнере док-станции, что и Обозреватель решений в связанном стиле.

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

Чтобы окно инструмента отображалось по умолчанию, можно указать видимость в разных контекстах пользовательского интерфейса с помощью атрибута [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();
}

Размещение команд для окон инструментов обычно находится в разделе "Вид" —> другие окна в главном меню.

Вот и все. Поздравляем, вы создали окно пользовательского инструмента.

Получение исходного кода

Исходный код для этого рецепта можно найти в репозитории примеров.