Freigeben über


Exemplarische Vorgehensweise: Erstellen eines Randsymbols

Sie können die Darstellung von Editor-Seitenrändern mithilfe von benutzerdefinierten Editorerweiterungen anpassen. In dieser Anleitung wird eine benutzerdefinierte Glyphe am Indikatorrand platziert, wenn das Wort "todo" in einem Code-Kommentar angezeigt wird.

Erstellen eines MEF-Projekts

  1. Erstellen Sie ein C#VSIX-Projekt. (Wählen Sie im Dialogfeld "Neues Projekt " die Option "Visual C#/Erweiterbarkeit" und dann "VSIX Project" aus.) Benennen Sie die Lösung TodoGlyphTest.

  2. Fügen Sie ein Editor-Klassifiziererprojektelement hinzu. Weitere Informationen finden Sie unter Erstellen einer Erweiterung mit einer Editorelementvorlage.

  3. Löschen Sie die vorhandenen Klassendateien.

Definieren der Glyphe

Definieren Sie eine Glyphe, indem Sie die IGlyphFactory Schnittstelle ausführen.

So definieren Sie die Glyphe

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

  2. Fügen Sie den folgenden Code mithilfe von Deklarationen hinzu.

    using System.ComponentModel.Composition;
    using System.Windows;
    using System.Windows.Shapes;
    using System.Windows.Media;
    using System.Windows.Controls;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Formatting;
    using Microsoft.VisualStudio.Text.Tagging;
    using Microsoft.VisualStudio.Utilities;
    
  3. Fügen Sie eine Klasse mit dem Namen TodoGlyphFactory hinzu, die IGlyphFactory implementiert.

    internal class TodoGlyphFactory : IGlyphFactory
    
  4. Fügen Sie ein privates Feld hinzu, das die Dimensionen der Glyphe definiert.

    const double m_glyphSize = 16.0;
    
  5. Implementieren Sie GenerateGlyph durch Definition des Glyphen-Benutzeroberflächenelements (UI). TodoTag wird weiter unten in dieser Schritt-für-Schritt-Anleitung definiert.

    public UIElement GenerateGlyph(IWpfTextViewLine line, IGlyphTag tag)
    {
        // Ensure we can draw a glyph for this marker.
        if (tag == null || !(tag is TodoTag))
        {
            return null;
        }
    
        System.Windows.Shapes.Ellipse ellipse = new Ellipse();
        ellipse.Fill = Brushes.LightBlue;
        ellipse.StrokeThickness = 2;
        ellipse.Stroke = Brushes.DarkBlue;
        ellipse.Height = m_glyphSize;
        ellipse.Width = m_glyphSize;
    
        return ellipse;
    }
    
  6. Fügen Sie eine Klasse mit dem Namen TodoGlyphFactoryProvider hinzu, die IGlyphFactoryProvider implementiert wird. Exportieren Sie diese Klasse mit einer NameAttribute von "TodoGlyph", einer OrderAttribute von "After VsTextMarker", einem ContentTypeAttribute von "code" und einem TagTypeAttribute von "TodoTag".

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
  7. Implementieren Sie die GetGlyphFactory Methode durch Instanziieren der TodoGlyphFactory.

    public IGlyphFactory GetGlyphFactory(IWpfTextView view, IWpfTextViewMargin margin)
    {
        return new TodoGlyphFactory();
    }
    

Definieren eines Todo-Tags und Taggers

Definieren Sie die Beziehung zwischen dem UI-Element, das Sie in den vorherigen Schritten und dem Indikatorrand definiert haben. Erstellen Sie einen Tagtyp und einen Tagger, und exportieren Sie ihn mithilfe eines Tagger-Anbieters.

So definieren Sie ein Todo-Tag und einen Tagger

  1. Fügen Sie dem Projekt eine neue Klassendatei hinzu, und nennen Sie sie TodoTagger.

  2. Fügen Sie die folgenden Importe hinzu.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Tagging;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Classification;
    using Microsoft.VisualStudio.Utilities;
    
  3. Fügen Sie eine Klasse mit dem Namen TodoTaghinzu.

    internal class TodoTag : IGlyphTag
    
  4. Ändern Sie die Klasse TodoTagger, die TodoTag vom Typ ITagger<T> implementiert.

    internal class TodoTagger : ITagger<TodoTag>
    
  5. Fügen Sie der TodoTagger Klasse private Felder für ein IClassifier und für den Text hinzu, der in den Klassifikationsspannen zu finden ist.

    private IClassifier m_classifier;
    private const string m_searchText = "todo";
    
  6. Fügen Sie einen Konstruktor hinzu, der den Klassifizierer festlegt.

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. Implementieren Sie die GetTags Methode, indem Sie nach allen Klassifizierungen suchen, deren Namen das Wort "Comment" enthalten und dessen Text den Suchtext enthält. Wenn der Suchtext gefunden wird, geben Sie einen neuen TagSpan<T> vom Typ TodoTag zurück.

    IEnumerable<ITagSpan<TodoTag>> ITagger<TodoTag>.GetTags(NormalizedSnapshotSpanCollection spans)
    {
        foreach (SnapshotSpan span in spans)
        {
            //look at each classification span \
            foreach (ClassificationSpan classification in m_classifier.GetClassificationSpans(span))
            {
                //if the classification is a comment
                if (classification.ClassificationType.Classification.ToLower().Contains("comment"))
                {
                    //if the word "todo" is in the comment,
                    //create a new TodoTag TagSpan
                    int index = classification.Span.GetText().ToLower().IndexOf(m_searchText);
                    if (index != -1)
                    {
                        yield return new TagSpan<TodoTag>(new SnapshotSpan(classification.Span.Start + index, m_searchText.Length), new TodoTag());
                    }
                }
            }
        }
    }
    
  8. Deklarieren eines Ereignisses TagsChanged .

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Fügen Sie eine Klasse mit dem Namen TodoTaggerProvider hinzu, die ITaggerProvider umsetzt, und exportieren Sie sie mit einem ContentTypeAttribute von "Code" und einem TagTypeAttribute von TodoTag.

    [Export(typeof(ITaggerProvider))]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    class TodoTaggerProvider : ITaggerProvider
    
  10. Importieren Sie die IClassifierAggregatorService.

    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. Implementieren Sie die CreateTagger-Methode, indem Sie TodoTagger instanziieren.

    public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
    {
        if (buffer == null)
        {
            throw new ArgumentNullException("buffer");
        }
    
        return new TodoTagger(AggregatorService.GetClassifier(buffer)) as ITagger<T>;
    }
    

Erstellen und Testen des Codes

Um diesen Code zu testen, erstellen Sie die TodoGlyphTest-Lösung, und führen Sie sie in der experimentellen Instanz aus.

So erstellen und testen Sie die TodoGlyphTest-Lösung

  1. Erstellen Sie die Lösung.

  2. Führen Sie das Projekt aus, indem Sie F5 drücken. Eine zweite Instanz von Visual Studio wird gestartet.

  3. Stellen Sie sicher, dass der Indikatorrand angezeigt wird.

    Vergewissern Sie sich im Bereich Tools>Optionen, unter dem Abschnitt Alle Einstellungen>Texteditor>Allgemein>Anzeige, dass das Kontrollkästchen "Indikatorrand anzeigen" aktiviert ist.

    Bestätigen Sie im Dialogfeld Extras>Optionen, im Abschnitt Text-Editor>Allgemein>Anzeige, dass das Kontrollkästchen Indikatorrand aktiviert ist.

  4. Öffnen Sie eine Codedatei mit Kommentaren. Fügen Sie das Wort "Todo" zu einem der Kommentarabschnitte hinzu.

  5. Ein hellblauer Kreis mit einem dunkelblauen Umriss wird links neben dem Codefenster im Indikatorrand angezeigt.