Étendre des documents Visual Studio
Un document est la représentation en mémoire d’un fichier ouvert dans Visual Studio. Il est référencé par moniker, qui est un absolu Uri
utilisant le file://
schéma. Un document est représenté par la DocumentSnapshot
classe, qui a les propriétés suivantes :
Moniker
IsDirty
IsReadOnly
IsInitialized
L’objet DocumentsExtensibility
fournit différentes méthodes utilisées pour obtenir et utiliser des DocumentSnapshot
instances d’objet.
Utiliser des documents
Ce guide est conçu pour couvrir les principaux scénarios utilisateur lors de l’utilisation de documents :
Ouvrir un document
Étant donné le chemin d’accès à un fichier sur disque, il est simple d’ouvrir le fichier dans Visual Studio :
DocumentsExtensibility documents = this.Extensibility.Documents();
Uri uri = new Uri(@"C:\path\to\Class1.cs", UriKind.Absolute);
DocumentSnapshot document = await documents.OpenDocumentAsync(uri, cancellationToken);
// optionally do something with the document
Obtenir un document texte instantané
Il DocumentSnapshot
s’agit d’une représentation abstraite d’un document. Si vous souhaitez lire ou écrire le texte dans un DocumentSnapshot
, vous pouvez le faire à l’aide de l’interface ITextDocumentSnapshot
, qui peut être obtenue avec la AsTextDocumentAsync
méthode d’extension pour DocumentSnapshot
.
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
DocumentsExtensibility documents = this.Extensibility.Documents();
Uri moniker = await context.GetSelectedPathAsync(cancellationToken);
DocumentSnapshot document = await documents.GetDocumentAsync(moniker, cancellationToken);
ITextDocumentSnapshot snapshot = await document.AsTextDocumentAsync(this.Extensibility, cancellationToken);
// insert the current date/time
EditorExtensibility editor = this.Extensibility.Editor();
using ITextViewSnapshot textView = await context.GetActiveTextViewAsync(cancellationToken);
await editor.EditAsync(
batch => snapshot.AsEditable(batch).Replace(textView.Selection.Extent, DateTime.Now.ToString()),
cancellationToken);
}
Réagir aux événements liés aux documents
Il existe des scénarios où les composants peuvent vouloir réagir aux événements liés aux documents (c’est-à-dire, lorsqu’ils sont ouverts, fermés ou enregistrés). Pour ce faire, implémentez l’interface IDocumentEventsListener
et utilisez cette option DocumentsExtensibility.SubscribeAsync
pour configurer l’abonnement aux événements.
internal sealed class SubscribeCommand : Command, IToggleCommand
{
private IDisposable? subscription;
bool? IToggleCommand.IsChecked => this.subscription is not null;
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
if (this.subscription is null)
{
// subscribe for events
this.subscription = await Subscription.CreateInstanceAsync(this.Extensibility, cancellationToken);
}
else
{
// remove the event subscription
this.subscription.Dispose();
this.subscription = null;
}
this.OnPropertyChanged(new PropertyChangedEventArgs(nameof(IToggleCommand.IsChecked)));
}
private class Subscription : IDisposable, IDocumentEventsListener
{
private readonly OutputWindowExtensibility output;
private IDisposable? rawSubscription;
private Subscription(VisualStudioExtensibility extensibility)
{
this.output = extensibility.Views().Output;
}
public static async Task<Subscription> CreateInstanceAsync(
VisualStudioExtensibility extensibility,
CancellationToken cancellationToken)
{
var subscription = new Subscription(extensibility);
DocumentsExtensibility documents = extensibility.Documents();
subscription.rawSubscription = await documents.SubscribeAsync(subscription, filterRegex: null, cancellationToken);
return subscription;
}
public void Dispose()
{
this.rawSubscription?.Dispose();
this.rawSubscription = null;
}
Task IDocumentEventsListener.ClosedAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.ClosedAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.HiddenAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.HiddenAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.OpenedAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.OpenedAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.RenamedAsync(RenamedDocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.RenamedAsync ({e.OldMoniker} -> {e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.SavedAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.SavedAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.SavingAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.SavingAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.ShownAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.ShownAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
private async Task OutputEventTextAsync(string text, CancellationToken token)
{
using OutputWindow outputWindow = await this.output.GetChannelAsync(
identifier: "Document Sample Command Output",
displayNameResourceId: nameof(Strings.DocumentsSampleOutputWindowPaneName),
token);
await outputWindow.Writer.WriteLineAsync($"Event received: {text}");
}
}
}
Étapes suivantes
- Suivez le guide de démarrage rapide de création du projet dans la section Prise en main.