Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Cree una ventana de herramientas acoplable con la interfaz de usuario enlazada a datos mediante la interfaz de usuario remota y el SDK de extensibilidad de VisualStudio.Extensibility.
Note
Esta guía usa el SDK de VisualStudio.Extensibility. Consulte Elección del modelo de extensibilidad adecuado para comparar los modelos.
Ejemplo completo
La implementación completa:
Definición de la ventana de herramientas:
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace ToolWindowSample;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Commands;
using Microsoft.VisualStudio.Extensibility.ToolWindows;
using Microsoft.VisualStudio.RpcContracts.RemoteUI;
/// <summary>
/// A sample tool window.
/// </summary>
[VisualStudioContribution]
public class MyToolWindow : ToolWindow
{
private object? dataContext;
/// <summary>
/// Initializes a new instance of the <see cref="MyToolWindow" /> class.
/// </summary>
public MyToolWindow()
{
this.Title = "My Tool Window";
}
/// <inheritdoc />
public override ToolWindowConfiguration ToolWindowConfiguration => new()
{
Placement = ToolWindowPlacement.DocumentWell,
Toolbar = new ToolWindowToolbar(Toolbar),
};
[VisualStudioContribution]
private static ToolbarConfiguration Toolbar => new("%ToolWindowSample.MyToolWindow.Toolbar.DisplayName%")
{
Children = [ToolbarChild.Command<MyToolbarCommand>()],
};
/// <inheritdoc />
public override Task InitializeAsync(CancellationToken cancellationToken)
{
this.dataContext = new MyToolWindowData(this.Extensibility);
return Task.CompletedTask;
}
/// <inheritdoc />
public override Task<IRemoteUserControl> GetContentAsync(CancellationToken cancellationToken)
{
return Task.FromResult<IRemoteUserControl>(new MyToolWindowControl(this.dataContext));
}
}
Comando para abrir la ventana de herramientas:
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace ToolWindowSample;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Commands;
/// <summary>
/// A sample command for showing a tool window.
/// </summary>
[VisualStudioContribution]
public class MyToolWindowCommand : Command
{
/// <inheritdoc />
public override CommandConfiguration CommandConfiguration => new("%ToolWindowSample.MyToolWindowCommand.DisplayName%")
{
Placements = [CommandPlacement.KnownPlacements.ToolsMenu],
Icon = new(ImageMoniker.KnownValues.ToolWindow, IconSettings.IconAndText),
};
/// <inheritdoc />
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
await this.Extensibility.Shell().ShowToolWindowAsync<MyToolWindow>(activate: true, cancellationToken);
}
}
Tip
Consulte el ejemplo de trabajo completo: ToolWindowSample ↗
Conceptos relacionados:Interfaz de usuario remota: el modelo de enlace de datos que se usa para el contenido de la ventana de herramientas, las contribuciones y las configuraciones: cómo se declaran las contribuciones de la ventana de herramientas
Entiende el ejemplo
Paso 1: Definir la clase de ventana de herramientas
Extiéndalo ToolWindow y márquelo con [VisualStudioContribution]:
[VisualStudioContribution]
internal class MyToolWindow : ToolWindow
{
private MyDataModel? dataModel;
public MyToolWindow(VisualStudioExtensibility extensibility)
: base(extensibility)
{
Title = "My Tool Window";
}
public override ToolWindowConfiguration ToolWindowConfiguration => new()
{
Placement = ToolWindowPlacement.DocumentWell,
AllowAutoCreation = true,
};
public override async Task InitializeAsync(CancellationToken cancellationToken)
{
dataModel = new MyDataModel();
await dataModel.LoadAsync(cancellationToken);
}
public override Task<IRemoteUserControl> GetContentAsync(CancellationToken cancellationToken)
{
return Task.FromResult<IRemoteUserControl>(new MyToolWindowControl(dataModel!));
}
}
Paso 2: Crear el modelo de datos
Usa NotifyPropertyChangedObject con [DataContract] y [DataMember] para el enlace de datos de la interfaz de usuario remota:
[DataContract]
internal class MyDataModel : NotifyPropertyChangedObject
{
private string message = "Hello from the tool window!";
[DataMember]
public string Message
{
get => message;
set => SetProperty(ref message, value);
}
public async Task LoadAsync(CancellationToken cancellationToken)
{
// Load data asynchronously
}
}
Paso 3: Crear el control de interfaz de usuario remota
Agregue una RemoteUserControl clase y una plantilla de datos XAML coincidente.
MyToolWindowControl.cs:
internal class MyToolWindowControl : RemoteUserControl
{
public MyToolWindowControl(MyDataModel dataModel)
: base(dataContext: dataModel)
{
}
}
MyToolWindowControl.xaml : establezca la acción de compilación en EmbeddedResource (no page):
<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">
<StackPanel Margin="10">
<TextBlock Text="{Binding Message}" FontSize="14" />
</StackPanel>
</DataTemplate>
Important
El archivo XAML debe usar la acción de EmbeddedResource compilación. Si se establece en Page, la ventana de herramientas se mostrará vacía.
Paso 4: Agregar un comando para mostrar la ventana de herramientas
[VisualStudioContribution]
internal class ShowMyToolWindowCommand : Command
{
public ShowMyToolWindowCommand(VisualStudioExtensibility extensibility)
: base(extensibility)
{
}
public override CommandConfiguration CommandConfiguration => new("My Tool Window")
{
Placements = [CommandPlacement.KnownPlacements.ViewOtherWindowsMenu],
Icon = new(ImageMoniker.KnownValues.ToolWindow, IconSettings.IconAndText),
};
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
await Extensibility.Shell().ShowToolWindowAsync<MyToolWindow>(activate: true, cancellationToken);
}
}
Paso 5 (opcional): Agregar una barra de herramientas
Defina una barra de herramientas y haga referencia a ella en ToolWindowConfiguration:
[VisualStudioContribution]
public static ToolbarConfiguration MyToolbar => new("%MyToolbar.DisplayName%")
{
Children = [
ToolbarChild.Command<RefreshCommand>(),
ToolbarChild.Separator,
ToolbarChild.Command<ClearCommand>(),
],
};
public override ToolWindowConfiguration ToolWindowConfiguration => new()
{
Placement = ToolWindowPlacement.DocumentWell,
Toolbar = new(MyToolbar),
};
Tips
✅ HACER
- Marque los archivos XAML como acción de compilación EmbeddedResource (no Page).
- Usa
[DataContract]y[DataMember]en las propiedades de ViewModel para la interfaz de usuario remota. - Use
NotifyPropertyChangedObjectcomo base para los modelos de datos. - Inicialice los datos en
InitializeAsync(), cree la interfaz de usuario enGetContentAsync(). - Use
ShowToolWindowAsync<T>(activate: true)para mostrar desde los comandos.
❌ INCORRECTO
- No utilice WPF directamente: se requiere la interfaz de usuario remota para las extensiones fuera de proceso.
- No establezca la acción de compilación del XAML en
Page(la ventana de herramientas no se mostrará). - No cree recursos costosos en el constructor: use
InitializeAsync.
🔧 Solución de problemas
| Síntoma | Corregir |
|---|---|
| La ventana de herramientas está vacía | Comprobar que la acción de compilación xaml es EmbeddedResource |
| El enlace de datos no se actualiza | Asegúrese de que ViewModel hereda NotifyPropertyChangedObject y las propiedades tienen [DataMember] |
| La ventana no aparece | Compruebe que el comando llama correctamente a ShowToolWindowAsync |
| La barra de herramientas no se muestra | Verifique que ToolWindowConfiguration.Toolbar esté establecido |
Pasos siguientes
- Descripción general de la interfaz de usuario remota — comprenda el modelo de renderizado
- Agregar un comando : para abrir la ventana de herramientas
- Temas y colores — personaliza la interfaz de usuario