Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Glühbirnen sind Symbole im Visual Studio-Editor, die erweitert werden, um eine Reihe von Aktionen anzuzeigen, z. B. Korrekturen für Probleme, die von den integrierten Codeanalysatoren oder der Codeumgestaltung identifiziert werden.
In den Editoren für Visual C# und Visual Basic können Sie auch die .NET-Compilerplattform ("Roslyn") verwenden, um Eigene Codeanalysatoren mit Aktionen zu schreiben und zu verpacken, die Glühbirnen automatisch anzeigen. Weitere Informationen finden Sie unter:
Anleitung: Schreiben einer Visual Basic Diagnose und Codekorrektur
Andere Sprachen wie C++ bieten auch Glühbirnen für einige schnelle Aktionen, z. B. einen Vorschlag zum Erstellen einer Stubimplementierung dieser Funktion.
So sieht eine Glühbirne aus. In einem Visual Basic- oder Visual C#-Projekt wird unter einem ungültigen Variablennamen eine rote Wellenlinie angezeigt. Wenn Sie mit dem Mauszeiger auf den ungültigen Bezeichner zeigen, wird in der Nähe des Cursors eine Glühbirne angezeigt.

Wenn Sie auf den Abwärtspfeil durch die Glühbirne klicken, wird eine Reihe von vorgeschlagenen Aktionen zusammen mit einer Vorschau der ausgewählten Aktion angezeigt. In diesem Fall werden die Änderungen angezeigt, die an Ihrem Code vorgenommen werden, wenn Sie die Aktion ausführen.

Sie können Glühbirnen verwenden, um Ihre eigenen vorgeschlagenen Aktionen bereitzustellen. Beispielsweise können Sie Aktionen angeben, um geschweifte Klammern in eine neue Zeile oder an das Ende der vorherigen Zeile zu verschieben. Die folgende exemplarische Vorgehensweise veranschaulicht, wie Sie ein eine Glühbirne erstellen, die für das aktuelle Wort angezeigt wird und zwei empfohlene Aktionen beinhaltet: In Großbuchstaben umwandeln und In Kleinbuchstaben umwandeln.
Erstellen eines Projekts für verwaltetes Erweiterbarkeitsframework (MEF)
Erstellen Sie ein C#VSIX-Projekt. (Wählen Sie im Dialogfeld Neues ProjektVisual C# / Erweiterbarkeitaus, und VSIX-Projekt.) Benennen Sie die Lösung
LightBulbTest.Fügen Sie dem Projekt eine Elementvorlage für den Editor-Klassifizierer hinzu. Weitere Informationen finden Sie unter Erstellen einer Erweiterung mit einer Editorelementvorlage.
Löschen Sie die vorhandenen Klassendateien.
Fügen Sie den folgenden Verweis auf das Projekt hinzu, und legen Sie Lokal kopieren auf
Falsefest:Microsoft.VisualStudio.Language.Intellisense
Fügen Sie eine neue Klassendatei hinzu, und nennen Sie sie LightBulbTest.
Fügen Sie die folgenden using-Anweisungen hinzu:
using System; using System.Linq; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Utilities; using System.ComponentModel.Composition; using System.Threading;
Implementierung des Glühbirnen-Quellenanbieters
Löschen Sie in der LightBulbTest.cs Klassendatei die LightBulbTest-Klasse. Fügen Sie eine Klasse namens TestSuggestedActionsSourceProvider hinzu, die ISuggestedActionsSourceProviderimplementiert. Exportieren Sie das Element mit dem Namen Vorgeschlagene Aktionen testen und dem ContentTypeAttribute-Element „Text“.
[Export(typeof(ISuggestedActionsSourceProvider))] [Name("Test Suggested Actions")] [ContentType("text")] internal class TestSuggestedActionsSourceProvider : ISuggestedActionsSourceProviderImportieren Sie in der Quellanbieterklasse die ITextStructureNavigatorSelectorService, und fügen Sie sie als Eigenschaft hinzu.
[Import(typeof(ITextStructureNavigatorSelectorService))] internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }Implementieren Sie die CreateSuggestedActionsSource-Methode, um ein ISuggestedActionsSource-Objekt zurückzugeben. Die Quelle wird im nächsten Abschnitt erläutert.
public ISuggestedActionsSource CreateSuggestedActionsSource(ITextView textView, ITextBuffer textBuffer) { if (textBuffer == null || textView == null) { return null; } return new TestSuggestedActionsSource(this, textView, textBuffer); }
Implementiere die ISuggestedActionSource
Die vorgeschlagene Aktionsquelle ist für das Sammeln der vorgeschlagenen Aktionen und das Hinzufügen im richtigen Kontext verantwortlich. In diesem Fall ist der Kontext das aktuelle Wort, und die vorgeschlagenen Aktionen sind UpperCaseSuggestedAction und LowerCaseSuggestedAction, die im folgenden Abschnitt erläutert wird.
Fügen Sie eine Klasse TestSuggestedActionsSource- hinzu, die ISuggestedActionsSourceimplementiert.
internal class TestSuggestedActionsSource : ISuggestedActionsSourceFügen Sie private, schreibgeschützte Felder für den vorgeschlagenen Aktionsquellenanbieter, den Textpuffer und die Textansicht hinzu.
private readonly TestSuggestedActionsSourceProvider m_factory; private readonly ITextBuffer m_textBuffer; private readonly ITextView m_textView;Fügen Sie einen Konstruktor hinzu, der die privaten Felder festlegt.
public TestSuggestedActionsSource(TestSuggestedActionsSourceProvider testSuggestedActionsSourceProvider, ITextView textView, ITextBuffer textBuffer) { m_factory = testSuggestedActionsSourceProvider; m_textBuffer = textBuffer; m_textView = textView; }Fügen Sie eine private Methode hinzu, die das Wort zurückgibt, das sich derzeit unter dem Cursor befindet. Die folgende Methode untersucht die aktuelle Position des Cursors und fragt den Textstrukturnavigator nach dem Umfang des Worts. Wenn sich der Cursor auf einem Wort befindet, wird der TextExtent im Ausgabeparameter zurückgegeben, andernfalls wird der Parameter
outnull, und die Methode gibtfalsezurück.private bool TryGetWordUnderCaret(out TextExtent wordExtent) { ITextCaret caret = m_textView.Caret; SnapshotPoint point; if (caret.Position.BufferPosition > 0) { point = caret.Position.BufferPosition - 1; } else { wordExtent = default(TextExtent); return false; } ITextStructureNavigator navigator = m_factory.NavigatorService.GetTextStructureNavigator(m_textBuffer); wordExtent = navigator.GetExtentOfWord(point); return true; }Implementieren Sie die HasSuggestedActionsAsync-Methode. Der Editor ruft diese Methode auf, um herauszufinden, ob die Glühbirne angezeigt werden soll. Dieser Aufruf wird häufig ausgeführt, beispielsweise wenn der Cursor von einer Zeile zu einer anderen wechselt oder mit dem Mauszeiger auf eine Wellenlinie für einen Fehler gezeigt wird. Er ist asynchron, damit weitere Vorgängen auf der Benutzeroberfläche während dieser Methode weiterhin ausgeführt werden können. In den meisten Fällen muss diese Methode etwas Parsing und Analyse der aktuellen Zeile durchführen, sodass die Verarbeitung einige Zeit in Anspruch nehmen kann.
In dieser Implementierung ruft er TextExtent asynchron ab und bestimmt, ob das Ausmaß erheblich ist und neben Leerzeichen weiterer Text vorhanden ist.
public Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { return Task.Factory.StartNew(() => { TextExtent extent; if (TryGetWordUnderCaret(out extent)) { // don't display the action if the extent has whitespace return extent.IsSignificant; } return false; }); }Implementieren Sie die GetSuggestedActions-Methode, die ein Array von SuggestedActionSet Objekten zurückgibt, die die verschiedenen ISuggestedAction Objekte enthalten. Diese Methode wird aufgerufen, wenn die Glühbirne erweitert wird.
Warnung
Sie sollten sicherstellen, dass die Implementierungen von
HasSuggestedActionsAsync()undGetSuggestedActions()konsistent sind; wennHasSuggestedActionsAsync()truezurückgibt, sollteGetSuggestedActions()einige Aktionen anzeigen. In vielen Fällen wirdHasSuggestedActionsAsync()kurz vorGetSuggestedActions()aufgerufen, aber dies ist nicht immer der Fall. Beispielsweise wird nurGetSuggestedActions()aufgerufen, wenn der Benutzer die Glühbirnenaktionen durch Drücken von (STRG+ .) aktiviert.public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { TextExtent extent; if (TryGetWordUnderCaret(out extent) && extent.IsSignificant) { ITrackingSpan trackingSpan = range.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive); var upperAction = new UpperCaseSuggestedAction(trackingSpan); var lowerAction = new LowerCaseSuggestedAction(trackingSpan); return new SuggestedActionSet[] { new SuggestedActionSet(new ISuggestedAction[] { upperAction, lowerAction }) }; } return Enumerable.Empty<SuggestedActionSet>(); }Definieren Sie ein
SuggestedActionsChanged-Ereignis.public event EventHandler<EventArgs> SuggestedActionsChanged;Um die Implementierung abzuschließen, fügen Sie Implementierungen für die methoden
Dispose()undTryGetTelemetryId()hinzu. Sie möchten keine Telemetrie ausführen. Geben Sie also einfachfalsezurück, und legen Sie die GUID aufEmptyfest.public void Dispose() { } public bool TryGetTelemetryId(out Guid telemetryId) { // This is a sample provider and doesn't participate in LightBulb telemetry telemetryId = Guid.Empty; return false; }
Implementieren von Glühbirnenaktionen
Fügen Sie im Projekt einen Verweis auf Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll hinzu, und setzen Sie Copy Local auf
False.Erstellen Sie zwei Klassen, den ersten benannten
UpperCaseSuggestedActionund den zweiten benanntenLowerCaseSuggestedAction. Beide Klassen implementieren ISuggestedAction.internal class UpperCaseSuggestedAction : ISuggestedAction internal class LowerCaseSuggestedAction : ISuggestedActionBeide Klassen sind gleich, mit der Ausnahme, dass die eine ToUpper und die andere ToLoweraufruft. In den folgenden Schritten wird nur die Klasse für die Umwandlung in Großbuchstaben behandelt, allerdings müssen Sie beide Klassen implementieren. Verwenden Sie diese Schritte als Muster für die Implementierung der Aktion zur Umwandlung in Kleinbuchstaben.
Fügen Sie die folgenden using-Anweisungen für diese Klassen hinzu:
using Microsoft.VisualStudio.Imaging.Interop; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media;Deklarieren Sie einen Satz privater Felder.
private ITrackingSpan m_span; private string m_upper; private string m_display; private ITextSnapshot m_snapshot;Fügen Sie einen Konstruktor hinzu, der die Felder festlegt.
public UpperCaseSuggestedAction(ITrackingSpan span) { m_span = span; m_snapshot = span.TextBuffer.CurrentSnapshot; m_upper = span.GetText(m_snapshot).ToUpper(); m_display = string.Format("Convert '{0}' to upper case", span.GetText(m_snapshot)); }Implementieren Sie die GetPreviewAsync-Methode, sodass sie die Aktionsvorschau anzeigt.
public Task<object> GetPreviewAsync(CancellationToken cancellationToken) { var textBlock = new TextBlock(); textBlock.Padding = new Thickness(5); textBlock.Inlines.Add(new Run() { Text = m_upper }); return Task.FromResult<object>(textBlock); }Implementieren Sie die GetActionSetsAsync-Methode, sodass sie eine leere SuggestedActionSet Enumeration zurückgibt.
public Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken) { return Task.FromResult<IEnumerable<SuggestedActionSet>>(null); }Implementieren Sie die Eigenschaften wie folgt.
public bool HasActionSets { get { return false; } } public string DisplayText { get { return m_display; } } public ImageMoniker IconMoniker { get { return default(ImageMoniker); } } public string IconAutomationText { get { return null; } } public string InputGestureText { get { return null; } } public bool HasPreview { get { return true; } }Implementieren Sie die Invoke-Methode, indem Sie den Text im Bereich durch entsprechende Großbuchstaben ersetzen.
public void Invoke(CancellationToken cancellationToken) { m_span.TextBuffer.Replace(m_span.GetSpan(m_snapshot), m_upper); }Warnung
Es wird nicht erwartet, dass die Glühbirnenaktion für die Methode zum Aufrufen auf der Benutzeroberfläche angezeigt wird. Wenn Ihre Aktion neue UI-Elemente (z. B. ein Vorschau- oder Auswahldialogfeld) anzeigt, zeigen Sie die Benutzeroberfläche nicht direkt aus der Invoke-Methode an, sondern planen Sie stattdessen, die Benutzeroberfläche anzuzeigen, nachdem Sie von Invokezurückgekehrt sind.
Um die Implementierung abzuschließen, fügen Sie die Methoden
Dispose()undTryGetTelemetryId()hinzu.public void Dispose() { } public bool TryGetTelemetryId(out Guid telemetryId) { // This is a sample action and doesn't participate in LightBulb telemetry telemetryId = Guid.Empty; return false; }Vergessen Sie nicht, dasselbe auch für
LowerCaseSuggestedActionzu tun, indem Sie den Anzeigetext in " '{0}' in Kleinbuchstaben umwandeln" und den Aufruf ToUpper in ToLowerändern.
Erstellen und Testen des Codes
Um diesen Code zu testen, erstellen Sie die LightBulbTest-Lösung, und führen Sie sie in der Experimental-Instanz aus.
Erstellen Sie die Lösung.
Wenn Sie dieses Projekt im Debugger ausführen, wird eine zweite Instanz von Visual Studio gestartet.
Erstellen Sie eine Textdatei, und geben Sie Text ein. Sie sollten links neben dem Text eine Glühbirne sehen.

Zeigen Sie auf die Glühbirne. Es sollte ein Pfeil nach unten angezeigt werden.
Wenn Sie auf die Glühbirne klicken, sollten zwei vorgeschlagene Aktionen zusammen mit der Vorschau der ausgewählten Aktion angezeigt werden.

Wenn Sie auf die erste Aktion klicken, sollte der gesamte Text im aktuellen Wort in Großbuchstaben konvertiert werden. Wenn Sie auf die zweite Aktion klicken, sollte der gesamte Text in Kleinbuchstaben konvertiert werden.