Freigeben über


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

  1. Erstellen Sie ein Projekt Editor-Klassifizierungs. Geben Sie der Projektmappe SmartTagTest.

  2. Öffnen Sie die Datei source.extension.vsixmanifest im VSIX-Manifest-Editor.

  3. Überprüfen Sie, ob die Content Überschrift einen MEF-Komponenten-Inhaltstyp enthält und dass Path zu SmartTagTest.dll festgelegt ist.

  4. Speichern und schließen Sie source.extension.vsixmanifest.

  5. Fügen Sie den folgenden Verweis auf das Projekt, und falsefestlegen CopyLocal hinzu:

    Microsoft.VisualStudio.Language.Intellisense

  6. Löschen Sie die vorhandenen Klassendateien.

Implementieren eines Tagger für Smarttags

So fügen Sie einen Tagger für Smarttags implementieren

  1. Fügen Sie eine Klassendatei hinzu, und nennen Sie sie TestSmartTag.

  2. 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;
    
  3. Fügen Sie eine Klasse hinzu, die TestSmartTag , die von SmartTagerbt.

    Friend Class TestSmartTag
        Inherits SmartTag
    
    internal class TestSmartTag : SmartTag
    
  4. 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) { }
    
  5. 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
    
  6. 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;
    
  7. 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;
    }
    
  8. 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;
        }
    }
    
  9. 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();
    }
    
  10. Deklarieren Sie das SmartTagsChanged-Ereignis.

    Public Event TagsChanged As EventHandler(Of SnapshotSpanEventArgs) Implements ITagger(Of TestSmartTag).TagsChanged
    
    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  11. 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));
            }
        }
    }
    
  12. 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

  1. 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
    
  2. Importieren Sie ITextStructureNavigatorSelectorService als Eigenschaft.

    <Import(GetType(ITextStructureNavigatorSelectorService))>
    Friend Property NavigatorService() As ITextStructureNavigatorSelectorService
    
    [Import(typeof(ITextStructureNavigatorSelectorService))]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
  3. 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.

  1. 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;
    
  2. 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";
    }
    
  3. 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; }
    }
    
  4. 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

  1. Erstellen Sie die Projektmappe.

  2. Wenn Sie dieses Projekt im Debugger ausführen, wird eine zweite Instanz von Visual Studio instanziiert.

  3. Erstellen Sie eine Textdatei, und geben Sie Text ein.

    Eine blaue Zeile sollte unter dem ersten Buchstaben des ersten Worts des Texts angezeigt werden.

  4. Bewegen Sie den Zeiger über die blaue Linie.

    Eine Schaltfläche sollte neben dem Zeiger angezeigt werden.

  5. 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