Exemplarische Vorgehensweise: SmartTags anzeigen
Smarttags sind für Text, Tags erweitert werden, um einen Satz von Aktionen anzuzeigen. Beispielsweise kann in einem Visual Basic- oder Visual C#-Projekt, wird eine rote Linie zwischen einem Wort, wenn ein Variablenname wie Sie einen Bezeichner umbenennen. Wenn Sie den Mauszeiger über den Unterstrich verschieben, wird eine Schaltfläche neben dem Zeiger angezeigt. Wenn Sie auf die Schaltfläche klicken, wird eine vorgeschlagene Aktion zum Beispiel IsRead in IsReady umbenennenangezeigt. Wenn Sie auf die Aktion klicken, werden alle Verweise auf IsRead im Projekt IsReady umbenannt.
Obwohl Smarttags Teil der IntelliSense-Implementierung im Editor sind, können Sie Smarttags implementieren, indem Sie SmartTagunterordnen, und dann die ITagger-Schnittstelle und die IViewTaggerProvider-Schnittstelle implementieren.
Hinweis
Andere Arten von Tags können auf eine ähnliche Weise implementiert werden.
Die folgende exemplarische Vorgehensweise zeigt, wie Sie ein Smarttag erstellen, das auf das aktuelle Wort vorkommt und zwei vorgeschlagene Aktionen: In Großbuchstaben konvertieren und In Kleinbuchstaben konvertieren.
Vorbereitungsmaßnahmen
Zum Abschließen dieser exemplarischen Vorgehensweise müssen Sie Visual Studio 2010 SDKinstallieren.
Hinweis
Weitere Informationen über das Visual Studio-SDK finden Sie unter Erweitern von Visual Studio Overview.Um herauszufinden finden Sie unter wie das Visual Studio-SDK, auf Visual Studio Extensibility Developer Center der MSDN-Website herunterlädt.
Ein Projekt des Managed Extensibility Framework (MEF)
So erstellen Sie ein MEF-Projekt
Erstellen Sie ein Projekt Editor-Klassifizierungs. Geben Sie der Projektmappe SmartTagTest.
Öffnen Sie die Datei source.extension.vsixmanifest im VSIX-Manifest-Editor.
Überprüfen Sie, ob die Content Überschrift einen MEF-Komponenten-Inhaltstyp enthält und dass Path zu SmartTagTest.dll festgelegt ist.
Speichern und schließen Sie source.extension.vsixmanifest.
Fügen Sie den folgenden Verweis auf das Projekt, und falsefestlegen CopyLocal hinzu:
Microsoft.VisualStudio.Language.Intellisense
Löschen Sie die vorhandenen Klassendateien.
Implementieren eines Tagger für Smarttags
So fügen Sie einen Tagger für Smarttags implementieren
Fügen Sie eine Klassendatei hinzu, und nennen Sie sie TestSmartTag.
Fügen Sie die folgenden Importe hinzu:
Imports System Imports System.Collections.Generic Imports System.ComponentModel.Composition Imports System.Collections.ObjectModel Imports System.Windows.Media Imports Microsoft.VisualStudio.Language.Intellisense Imports Microsoft.VisualStudio.Text Imports Microsoft.VisualStudio.Text.Editor Imports Microsoft.VisualStudio.Text.Operations Imports Microsoft.VisualStudio.Text.Tagging Imports Microsoft.VisualStudio.Utilities
using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Collections.ObjectModel; using System.Windows.Media; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Text.Tagging; using Microsoft.VisualStudio.Utilities;
Fügen Sie eine Klasse hinzu, die TestSmartTag , die von SmartTagerbt.
Friend Class TestSmartTag Inherits SmartTag
internal class TestSmartTag : SmartTag
Fügen Sie einen Konstruktor für diese Klasse hinzu, die den Basiskonstruktor mit SmartTagType von Factoidaufruft, die eine blaue Zeile wird unter dem ersten Zeichen eines Worts angezeigt wird. (Wenn Sie Ephemeralverwenden, wird eine rote Linie unter dem letzten Zeichen des Worts.)
Public Sub New(ByVal actionSets As ReadOnlyCollection(Of SmartTagActionSet)) MyBase.New(SmartTagType.Factoid, actionSets) End Sub
public TestSmartTag(ReadOnlyCollection<SmartTagActionSet> actionSets) : base(SmartTagType.Factoid, actionSets) { }
Fügen Sie eine Klasse hinzu, die TestSmartTagger benannt wird, die von ITagger des Typs TestSmartTagerbt, und implementiert IDisposable.
Friend Class TestSmartTagger Implements ITagger(Of TestSmartTag), IDisposable
internal class TestSmartTagger : ITagger<TestSmartTag>, IDisposable
Fügen Sie die folgenden privaten Felder der Tagger - Klasse hinzu.
Private m_buffer As ITextBuffer Private m_view As ITextView Private m_provider As TestSmartTaggerProvider Private m_disposed As Boolean
private ITextBuffer m_buffer; private ITextView m_view; private TestSmartTaggerProvider m_provider; private bool m_disposed;
Fügen Sie einen Konstruktor, der die privaten Felder hinzu und ändert, abonniert LayoutChanged das Ereignis.
Public Sub New(ByVal buffer As ITextBuffer, ByVal view As ITextView, ByVal provider As TestSmartTaggerProvider) m_buffer = buffer m_view = view m_provider = provider AddHandler m_view.LayoutChanged, AddressOf OnLayoutChanged End Sub
public TestSmartTagger(ITextBuffer buffer, ITextView view, TestSmartTaggerProvider provider) { m_buffer = buffer; m_view = view; m_provider = provider; m_view.LayoutChanged += OnLayoutChanged; }
Implementieren Sie GetTags , damit das Tag für das aktuelle Wort erstellt wird. (Diese Methode ruft außerdem eine private Methode GetSmartTagActions an, die später erläutert.)
Public Function GetTags(ByVal spans As NormalizedSnapshotSpanCollection) As IEnumerable(Of ITagSpan(Of TestSmartTag)) Implements ITagger(Of TestSmartTag).GetTags Dim snapshot As ITextSnapshot = m_buffer.CurrentSnapshot If snapshot.Length = 0 Then Return Nothing Exit Function End If 'set up the navigator Dim navigator As ITextStructureNavigator = m_provider.NavigatorService.GetTextStructureNavigator(m_buffer) 'set up a list to contain the tags Dim list As List(Of TagSpan(Of TestSmartTag)) list = New List(Of TagSpan(Of TestSmartTag))() For Each span In spans Dim caret As ITextCaret = m_view.Caret Dim point As SnapshotPoint If CInt(caret.Position.BufferPosition) > 0 Then point = caret.Position.BufferPosition - 1 Else Exit For End If Dim extent As TextExtent = navigator.GetExtentOfWord(point) 'don't display the tag if the extent has whitespace If extent.IsSignificant Then list.Add(New TagSpan(Of TestSmartTag)(extent.Span, New TestSmartTag(GetSmartTagActions(extent.Span)))) Else Exit For End If Next span Return list End Function
public IEnumerable<ITagSpan<TestSmartTag>> GetTags(NormalizedSnapshotSpanCollection spans) { ITextSnapshot snapshot = m_buffer.CurrentSnapshot; if (snapshot.Length == 0) yield break; //don't do anything if the buffer is empty //set up the navigator ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_buffer); foreach (var span in spans) { ITextCaret caret = m_view.Caret; SnapshotPoint point; if (caret.Position.BufferPosition > 0) point = caret.Position.BufferPosition - 1; else yield break; TextExtent extent = navigator.GetExtentOfWord(point); //don't display the tag if the extent has whitespace if (extent.IsSignificant) yield return new TagSpan<TestSmartTag>(extent.Span, new TestSmartTag(GetSmartTagActions(extent.Span))); else yield break; } }
Fügen Sie eine GetSmartTagActions-Methode hinzu, um die Smarttagaktionen zu installieren. Die Aktionen selbst werden in späteren Schritten implementiert.
Private Function GetSmartTagActions(ByVal span As SnapshotSpan) As ReadOnlyCollection(Of SmartTagActionSet) Dim actionSetList As New List(Of SmartTagActionSet)() Dim actionList As New List(Of ISmartTagAction)() Dim trackingSpan As ITrackingSpan = span.Snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeInclusive) actionList.Add(New UpperCaseSmartTagAction(trackingSpan)) actionList.Add(New LowerCaseSmartTagAction(trackingSpan)) Dim actionSet As New SmartTagActionSet(actionList.AsReadOnly()) actionSetList.Add(actionSet) Return actionSetList.AsReadOnly() End Function
private ReadOnlyCollection<SmartTagActionSet> GetSmartTagActions(SnapshotSpan span) { List<SmartTagActionSet> actionSetList = new List<SmartTagActionSet>(); List<ISmartTagAction> actionList = new List<ISmartTagAction>(); ITrackingSpan trackingSpan = span.Snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeInclusive); actionList.Add(new UpperCaseSmartTagAction(trackingSpan)); actionList.Add(new LowerCaseSmartTagAction(trackingSpan)); SmartTagActionSet actionSet = new SmartTagActionSet(actionList.AsReadOnly()); actionSetList.Add(actionSet); return actionSetList.AsReadOnly(); }
Deklarieren Sie das SmartTagsChanged-Ereignis.
Public Event TagsChanged As EventHandler(Of SnapshotSpanEventArgs) Implements ITagger(Of TestSmartTag).TagsChanged
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
Implementieren Sie den OnLayoutChanged-Ereignishandler, um das TagsChanged-Ereignis auszulösen, das GetTags wird aufgerufen.
Private Sub OnLayoutChanged(ByVal sender As Object, ByVal e As TextViewLayoutChangedEventArgs) Dim snapshot As ITextSnapshot = e.NewSnapshot 'don't do anything if this is just a change in case If Not snapshot.GetText().ToLower().Equals(e.OldSnapshot.GetText().ToLower()) Then Dim span As New SnapshotSpan(snapshot, New Span(0, snapshot.Length)) Dim handler As EventHandler(Of SnapshotSpanEventArgs) = Me.TagsChangedEvent If handler IsNot Nothing Then handler(Me, New SnapshotSpanEventArgs(span)) End If End If End Sub
private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e) { ITextSnapshot snapshot = e.NewSnapshot; //don't do anything if this is just a change in case if (!snapshot.GetText().ToLower().Equals(e.OldSnapshot.GetText().ToLower())) { SnapshotSpan span = new SnapshotSpan(snapshot, new Span(0, snapshot.Length)); EventHandler<SnapshotSpanEventArgs> handler = this.TagsChanged; if (handler != null) { handler(this, new SnapshotSpanEventArgs(span)); } } }
Implementieren Sie die Dispose-Methode, sodass sie vom LayoutChanged-Ereignis kündigt.
Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Private Sub Dispose(ByVal disposing As Boolean) If disposing Then RemoveHandler m_view.LayoutChanged, AddressOf OnLayoutChanged m_view = Nothing End If m_disposed = True End Sub
public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!this.m_disposed) { if (disposing) { m_view.LayoutChanged -= OnLayoutChanged; m_view = null; } m_disposed = true; } }
Implementieren des Smarttag-Tagger-Anbieter
Um den Anbieter implementieren tagger Smarttag
Fügen Sie eine Klasse hinzu, die TestSmartTagTaggerProvider , die von IViewTaggerProvidererbt. Exportieren Sie ihn mit ContentTypeAttribute „des Texts“, OrderAttribute von Before= " default“ und TagTypeAttribute von SmartTag.
<Export(GetType(IViewTaggerProvider))> <ContentType("text")> <Order(Before:="default")> <TagType(GetType(SmartTag))> Friend Class TestSmartTaggerProvider Implements IViewTaggerProvider
[Export(typeof(IViewTaggerProvider))] [ContentType("text")] [Order(Before = "default")] [TagType(typeof(SmartTag))] internal class TestSmartTaggerProvider : IViewTaggerProvider
Importieren Sie ITextStructureNavigatorSelectorService als Eigenschaft.
<Import(GetType(ITextStructureNavigatorSelectorService))> Friend Property NavigatorService() As ITextStructureNavigatorSelectorService
[Import(typeof(ITextStructureNavigatorSelectorService))] internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
Implementieren Sie die CreateTagger``1-Methode.
Public Function CreateTagger(Of T As ITag)(ByVal textView As ITextView, ByVal buffer As ITextBuffer) As ITagger(Of T) Implements IViewTaggerProvider.CreateTagger If buffer Is Nothing OrElse textView Is Nothing Then Return Nothing End If 'make sure we are tagging only the top buffer If buffer Is textView.TextBuffer Then Return New TestSmartTagger(buffer, textView, Me) Else Return Nothing End If End Function
public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag { if (buffer == null || textView == null) { return null; } //make sure we are tagging only the top buffer if (buffer == textView.TextBuffer) { return new TestSmartTagger(buffer, textView, this) as ITagger<T>; } else return null; }
Implementieren Smarttag-Aktionen
So implementieren Sie die Smarttagaktionen
Erstellen Sie zwei Klassen, UpperCaseSmartTagAction benannte erste und zweite benannte LowerCaseSmartTagAction. Beide Klassen implementieren ISmartTagAction.
Friend Class UpperCaseSmartTagAction Implements ISmartTagAction
internal class UpperCaseSmartTagAction : ISmartTagAction
Friend Class LowerCaseSmartTagAction Implements ISmartTagAction
internal class LowerCaseSmartTagAction : ISmartTagAction
Beide Klassen sind gleich, außer dass ruft ToUpper an und ruft die andere ToLoweran. Die folgenden Schritte sind nur die großgeschriebene Aktionen class. Sie müssen jedoch beide Klassen implementiert werden. Verwenden Sie die Schritte zum Implementieren der großgeschriebenen Aktion als Muster für die Implementierung der Aktion aus Kleinbuchstaben.
Deklarieren Sie einen Satz von privaten Felder.
Private m_span As ITrackingSpan Private m_upper As String Private m_display As String Private m_snapshot As ITextSnapshot
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 veranschaulicht.
Public Sub New(ByVal span As ITrackingSpan) m_span = span m_snapshot = span.TextBuffer.CurrentSnapshot m_upper = span.GetText(m_snapshot).ToUpper() m_display = "Convert to upper case" End Sub
public UpperCaseSmartTagAction(ITrackingSpan span) { m_span = span; m_snapshot = span.TextBuffer.CurrentSnapshot; m_upper = span.GetText(m_snapshot).ToUpper(); m_display = "Convert to upper case"; }
Implementieren Sie die Eigenschaften wie folgt.
Public ReadOnly Property DisplayText() As String Implements ISmartTagAction.DisplayText Get Return m_display End Get End Property Public ReadOnly Property Icon() As ImageSource Implements ISmartTagAction.Icon Get Return Nothing End Get End Property Public ReadOnly Property IsEnabled() As Boolean Implements ISmartTagAction.IsEnabled Get Return True End Get End Property Private privateSource As ISmartTagSource Public Property Source() As ISmartTagSource Get Return privateSource End Get Private Set(ByVal value As ISmartTagSource) privateSource = value End Set End Property Public ReadOnly Property ActionSets() As ReadOnlyCollection(Of SmartTagActionSet) Implements ISmartTagAction.ActionSets Get Return Nothing End Get End Property
public string DisplayText { get { return m_display; } } public ImageSource Icon { get { return null; } } public bool IsEnabled { get { return true; } } public ISmartTagSource Source { get; private set; } public ReadOnlyCollection<SmartTagActionSet> ActionSets { get { return null; } }
Implementieren Sie die Invoke-Methode, indem Sie den Text in der Spanne mit ihrer großgeschriebenen Äquivalent ersetzen.
Public Sub Invoke() Implements ISmartTagAction.Invoke m_span.TextBuffer.Replace(m_span.GetSpan(m_snapshot), m_upper) End Sub
public void Invoke() { m_span.TextBuffer.Replace(m_span.GetSpan(m_snapshot), m_upper); }
Erstellen und Testen von Code
Um diesen Code zu testen, erstellen Sie die SmartTagTest-Projektmappe und führen Sie sie in der experimentellen Instanz aus.
So erstellen und testen die SmartTagTest-Projektmappe
Erstellen Sie die Projektmappe.
Wenn Sie dieses Projekt im Debugger ausführen, wird eine zweite Instanz von Visual Studio instanziiert.
Erstellen Sie eine Textdatei, und geben Sie Text ein.
Eine blaue Zeile sollte unter dem ersten Buchstaben des ersten Worts des Texts angezeigt werden.
Bewegen Sie den Zeiger über die blaue Linie.
Eine Schaltfläche sollte neben dem Zeiger angezeigt werden.
Wenn Sie auf die Schaltfläche klicken, schlugen, dass zwei Aktionen angezeigt werden sollten: In Großbuchstaben konvertieren und In Kleinbuchstaben konvertieren. Wenn Sie auf die erste Aktion klicken, muss der gesamte Text im aktuellen Wort an den Großbuchstaben konvertiert werden. Wenn Sie auf die zweite Aktion klicken, muss der gesamte Text in Kleinbuchstaben konvertiert wurden.
Siehe auch
Aufgaben
Exemplarische Vorgehensweise: Verknüpfen einer Dateinamenerweiterung eines Inhaltstyps