Crear ventanas de herramientas personalizadas
Las ventanas de herramientas personalizadas son excelentes opciones para agregar una interfaz de usuario compleja a Visual Studio.
Una ventana de herramientas es un concepto básico de interfaz de usuario en Visual Studio y en el vídeo siguiente se muestra cómo agregar una ventana personalizada.
Una ventana de herramientas es una ventana que se puede mover y acoplar igual que el Explorador de soluciones, la lista de errores y otras ventanas de herramientas conocidas. Una ventana de herramientas consta de un shell externo proporcionado por Visual Studio y un control de interfaz de usuario interno personalizado, que normalmente es un XAML <usercontrol>
proporcionado por la extensión.
Nota:
Para crear una nueva extensión con una ventana de herramientas, cree un nuevo proyecto con la plantilla VsIX Project w/Tool Window (Community) y omita el resto de esta receta. Consulta Introducción para obtener más información.
Agregar una ventana de herramientas a una extensión existente requiere 4 pasos sencillos:
- Cree una clase de shell exterior de ventana de herramientas.
- Agregue un XAML
<usercontrol>
a la ventana de herramientas. - Registre la ventana de herramientas.
- Cree un comando para mostrar la ventana de herramientas.
Comencemos con el paso 1.
Creación de la ventana de herramientas
Con la BaseToolWindow<T>
clase base genérica, se nos pide que proporcione algunos fragmentos básicos de información. Debemos especificar el título de la ventana de herramientas, crear y devolver el control de usuario XAML y establecer la clase real ToolWindowPane
usada por Visual Studio para crear el shell externo de la ventana.
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;
}
}
}
Debe crear una instancia del control de usuario personalizado desde el CreateAsync(int, CancellationToken)
método , que se pasa automáticamente al shell de la ventana de herramientas cuando visual Studio lo crea.
Pero primero debe crear el control de usuario.
Adición del control de usuario XAML
Puede ser cualquier XAML con su clase de código subyacente, por lo que este es un ejemplo sencillo de un elemento <usercontrol>
que contiene un solo botón:
<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>
Ahora tenemos nuestra clase de ventana de herramientas que devuelve nuestro control personalizado. El siguiente paso es registrar nuestra ventana de herramientas con Visual Studio.
Registro de la ventana de herramientas
Registrar la ventana de herramientas significa que estamos indicando a Visual Studio su existencia y cómo crear instancias de ella. Lo hacemos desde nuestra clase de paquete mediante el [ProvideToolWindow]
atributo .
[ProvideToolWindow(typeof(MyToolWindow.Pane))]
public sealed class MyPackage : ToolkitPackage
{
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
this.RegisterToolWindows();
}
}
Nota:
Tenga en cuenta que la clase de paquete debe heredar de ToolkitPackage
y no de Package
o AsyncPackage
.
Puede especificar el estilo que debe tener la ventana de herramientas y dónde debe aparecer de forma predeterminada. En el ejemplo siguiente se muestra que la ventana de herramientas debe colocarse en el mismo contenedor de acoplamiento que Explorador de soluciones en un estilo vinculado.
[ProvideToolWindow(typeof(MyToolWindow.Pane), Style = VsDockStyle.Linked, Window = WindowGuids.SolutionExplorer)]
Para que la ventana de herramientas sea visible de forma predeterminada, puede especificar su visibilidad en distintos contextos de interfaz de usuario mediante el [ProvideToolWindowVisibility]
atributo .
[ProvideToolWindowVisibility(typeof(MyToolWindow.Pane), VSConstants.UICONTEXT.NoSolution_string)]
Comando para mostrar la ventana de herramientas
Esto es lo mismo que cualquier otro comando, y puede ver cómo agregar uno en la receta Menús y comandos.
La clase de controlador de comandos que muestra la ventana de herramientas tendrá un aspecto similar al siguiente:
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();
}
La selección de ubicación de comandos para las ventanas de herramientas suele estar en Ver -> Otras ventanas en el menú principal.
Eso es. Enhorabuena, ha creado la ventana de herramientas personalizada.
Obtención del código fuente
Puede encontrar el código fuente de esta receta en el repositorio de ejemplos.