Udostępnij przez


Przewodnik: Utworzenie glifu marginesu

Wygląd marginesów edytora można dostosować przy użyciu niestandardowych rozszerzeń edytora. Ten przewodnik umieszcza niestandardowy glyph na marginesie wskaźnika za każdym razem, gdy słowo "todo" pojawia się w komentarzu kodu.

Tworzenie projektu MEF

  1. Utwórz projekt VSIX w języku C#. (W oknie dialogowym Nowy projekt wybierz pozycję Visual C# / Rozszerzalność, a następnie projekt VSIX). Nadaj rozwiązaniu TodoGlyphTestnazwę .

  2. Dodaj element projektu Klasyfikator edytora. Aby uzyskać więcej informacji, zobacz Tworzenie rozszerzenia za pomocą szablonu elementu edytora.

  3. Usuń istniejące pliki klas.

Definiowanie glifów

Zdefiniuj glif, uruchamiając IGlyphFactory interfejs.

Aby zdefiniować glif

  1. Dodaj plik klasy i nadaj mu TodoGlyphFactorynazwę .

  2. Dodaj następujący kod przy użyciu deklaracji.

    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. Dodaj klasę o nazwie TodoGlyphFactory, która implementuje IGlyphFactory.

    internal class TodoGlyphFactory : IGlyphFactory
    
  4. Dodaj pole prywatne, które definiuje wymiary glif.

    const double m_glyphSize = 16.0;
    
  5. Zaimplementuj GenerateGlyph , definiując element interfejsu użytkownika (UI). TodoTag zostanie zdefiniowany później w ramach tego przewodnika.

    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. Dodaj klasę o nazwie TodoGlyphFactoryProvider, która implementuje IGlyphFactoryProvider. Wyeksportuj tę klasę z wartością NameAttribute "TodoGlyph", wartością OrderAttribute After VsTextMarker, znakiem "code" i elementem ContentTypeAttributeTagTypeAttribute TodoTag.

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
  7. Zaimplementuj metodę GetGlyphFactory tworząc wystąpienie klasy TodoGlyphFactory.

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

Definiowanie tagu Todo i oznaczacza.

Zdefiniuj relację między elementem interfejsu użytkownika zdefiniowanym w poprzednich krokach i marginesem wskaźnika. Utwórz typ tagu oraz narzędzie tagujące i wyeksportuj je za pomocą dostawcy narzędzi tagujących.

Aby zdefiniować tag do zadań i tagger

  1. Dodaj nowy plik klasy do projektu i nadaj mu TodoTaggernazwę .

  2. Dodaj następujące importy.

    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. Dodaj klasę o nazwie TodoTag.

    internal class TodoTag : IGlyphTag
    
  4. Zmodyfikuj klasę TodoTagger , która implementuje ITagger<T> typu TodoTag.

    internal class TodoTagger : ITagger<TodoTag>
    
  5. W klasie TodoTagger dodaj pola prywatne dla IClassifier oraz dla tekstu, który ma być znaleziony w zakresach klasyfikacji.

    private IClassifier m_classifier;
    private const string m_searchText = "todo";
    
  6. Dodaj konstruktor, który ustawia klasyfikator.

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. Zaimplementuj metodę GetTags , wyszukując wszystkie zakresy klasyfikacji, których nazwy zawierają wyraz "komentarz" i którego tekst zawiera tekst wyszukiwania. Za każdym razem, gdy tekst wyszukiwania zostanie znaleziony, wróć do nowego TagSpan<T> typu TodoTag.

    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. Zadeklaruj TagsChanged zdarzenie.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Dodaj klasę o nazwie TodoTaggerProvider, która implementuje ITaggerProvider, i wyeksportuj ją z ContentTypeAttribute "code" oraz TagTypeAttribute TodoTag.

    [Export(typeof(ITaggerProvider))]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    class TodoTaggerProvider : ITaggerProvider
    
  10. Zaimportuj plik IClassifierAggregatorService.

    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. Zaimplementuj metodę CreateTagger, tworząc wystąpienie klasy TodoTagger.

    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>;
    }
    

Kompilowanie i testowanie kodu

Aby przetestować ten kod, skompiluj rozwiązanie TodoGlyphTest i uruchom je w wystąpieniu eksperymentalnym.

Aby skompilować i przetestować rozwiązanie TodoGlyphTest

  1. Skompiluj rozwiązanie.

  2. Uruchom projekt, naciskając F5. Druga instancja programu Visual Studio uruchamia się.

  3. Upewnij się, że margines wskaźnika jest wyświetlany.

    W okienku Narzędzia>Opcje, w sekcji wszystkie ustawienia>Edytor tekstu>Ogólne>Wyświetlanie, upewnij się, że zaznaczono pole wyboru Pokaż margines wskaźnika.

    W oknie dialogowym Narzędzia>Opcje, w sekcji Edytor tekstu>Ogólne>Wyświetlanie, upewnij się, że zaznaczono pole wyboru Margines wskaźnika.

  4. Otwórz plik kodu zawierający komentarze. Dodaj słowo "todo" do jednej z sekcji komentarzy.

  5. Jasnoniebieski okrąg z ciemnoniebieskim konturem pojawia się na marginesie wskaźnika po lewej stronie okna kodu.