Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Crea una finestra degli strumenti ancorabile con l'interfaccia utente associata ai dati usando l'interfaccia utente remota e l'SDK VisualStudio.Extensibility.
Note
Questa guida usa l'SDK VisualStudio.Extensibility. Vedere Scegliere il modello di estendibilità corretto per il confronto dei modelli.
Esempio completo
Implementazione completa:
Definizione della finestra degli strumenti:
// 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));
}
}
Il comando per aprire la finestra dello strumento:
// 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
Vedere l'esempio di lavoro completo: ToolWindowSample ↗
Concetti correlati:Interfaccia utente remota : modello di data binding usato per il contenuto della finestra degli strumenti, contributi e configurazioni , modalità di dichiarazione dei contributi delle finestre degli strumenti
Capire l’esempio
Passaggio 1: Definire la classe della finestra degli strumenti
Estendere ToolWindow e contrassegnarlo 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!));
}
}
Passaggio 2: Creare il modello di dati
Usare NotifyPropertyChangedObject con [DataContract] e [DataMember] per il data binding dell'interfaccia utente 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
}
}
Passaggio 3: Creare il controllo dell'interfaccia utente remota
Aggiungere una RemoteUserControl classe e un modello di dati XAML corrispondente.
MyToolWindowControl.cs:
internal class MyToolWindowControl : RemoteUserControl
{
public MyToolWindowControl(MyDataModel dataModel)
: base(dataContext: dataModel)
{
}
}
MyToolWindowControl.xaml — impostare l'azione di compilazione su EmbeddedResource (non 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
Il file XAML deve usare l'azione di EmbeddedResource compilazione. Impostandolo su Page, la finestra degli strumenti verrà visualizzata vuota.
Passaggio 4: Aggiungere un comando per visualizzare la finestra degli strumenti
[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);
}
}
Passaggio 5 (facoltativo): Aggiungere una barra degli strumenti
Definire una barra degli strumenti e farvi riferimento in 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
✅ DO
- Contrassegna i file XAML con azione di compilazione EmbeddedResource (non Page).
- Usare
[DataContract]e[DataMember]nelle proprietà ViewModel per l'interfaccia utente remota. - Usare
NotifyPropertyChangedObjectcome base per i modelli di dati. - Inizializzare i dati in
InitializeAsync(), creare l'interfaccia utente inGetContentAsync(). - Usare
ShowToolWindowAsync<T>(activate: true)per mostrare dai comandi.
❌ DON'T
- Non usare direttamente macchine virtuali Windows: l'interfaccia utente remota è necessaria per le estensioni out-of-process.
- Non impostare l'azione di compilazione XAML su
Page(la finestra degli strumenti non verrà visualizzata). - Non creare risorse costose nel costruttore : usare
InitializeAsync.
🔧 Risoluzione dei problemi
| Sintomo | Correzione |
|---|---|
| La finestra degli strumenti è vuota | Verificare che l'azione di compilazione XAML sia EmbeddedResource |
| Il data binding non si aggiorna | Verificare che ViewModel erediti NotifyPropertyChangedObject e le proprietà dispongano di [DataMember] |
| La finestra non viene visualizzata | Controllare che le chiamate di comando ShowToolWindowAsync siano corrette |
| Barra degli strumenti non visualizzata | Verificare che ToolWindowConfiguration.Toolbar sia impostato |
Passaggi successivi
- Panoramica dell'interfaccia utente remota — comprendere il modello di rendering
- Aggiungi un comando — per aprire la finestra degli strumenti
- Temi e colori — personalizza l'interfaccia utente