Walkthrough: Een marge-symbool maken

U kunt het uiterlijk van editormarges aanpassen met behulp van aangepaste editorextensies. In deze handleiding wordt een aangepaste glyph op de indicatormarge geplaatst telkens wanneer het woord 'todo' in een code-opmerking voorkomt.

Een MEF-project maken

  1. Maak een C# VSIX-project. (Selecteer in het dialoogvenster Nieuw projectVisual C# / Uitbreidbaarheid en vervolgens VSIX-project.) Geef de oplossing TodoGlyphTesteen naam.

  2. Voeg een Editor Classifier-projectitem toe. Zie Een extensie maken met een sjabloon voor editoritems voor meer informatie.

  3. Verwijder de bestaande klassebestanden.

Het symbool definiëren

Definieer een glyph door de interface uit te IGlyphFactory voeren.

Het symbool definiëren

  1. Voeg een klassebestand toe en geef het een TodoGlyphFactorynaam.

  2. Voeg de volgende code toe met behulp van declaraties.

    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. Voeg een klasse toe met de naam TodoGlyphFactory die IGlyphFactory implementeert.

    internal class TodoGlyphFactory : IGlyphFactory
    
  4. Voeg een privéveld toe waarmee de afmetingen van de glyph worden gedefinieerd.

    const double m_glyphSize = 16.0;
    
  5. Implementeer GenerateGlyph door het element glyph user interface (UI) te definiëren. TodoTag wordt later in deze handleiding gedefinieerd.

    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. Voeg een klasse toe met de naam TodoGlyphFactoryProvider die IGlyphFactoryProvider implementeert. Exporteer deze klasse met een NameAttribute van 'TodoGlyph', een OrderAttribute van After VsTextMarker, een ContentTypeAttribute van 'code' en een TagTypeAttribute van TodoTag.

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
  7. Implementeer de GetGlyphFactory methode door de TodoGlyphFactorymethode te instantiëren.

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

Een todo-tag en tagger definiëren

Definieer de relatie tussen het UI-element dat u in de vorige stappen en de indicatormarge hebt gedefinieerd. Maak een tagtype en tagger en exporteer het met behulp van een tagprovider.

Een todo-tag en tagger definiëren

  1. Voeg een nieuw klassebestand toe aan het project en geef het een TodoTaggernaam.

  2. Voeg de volgende importen toe.

    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. Voeg een klasse toe met de naam TodoTag.

    internal class TodoTag : IGlyphTag
    
  4. Wijzig de klasse genaamd TodoTagger, die ITagger<T> van het type TodoTag implementeert.

    internal class TodoTagger : ITagger<TodoTag>
    
  5. Voeg aan de TodoTagger klasse privévelden toe voor een IClassifier en voor de tekst die u in de classificatiebereiken kunt vinden.

    private IClassifier m_classifier;
    private const string m_searchText = "todo";
    
  6. Voeg een constructor toe waarmee de classificatie wordt ingesteld.

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. Implementeer de GetTags methode door alle classificaties te zoeken waarvan de namen het woord 'opmerking' bevatten en waarvan de tekst de zoektekst bevat. Wanneer de zoektekst wordt gevonden, geeft u een nieuwe TagSpan<T> van type TodoTag terug op.

    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. Declareer een TagsChanged gebeurtenis.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Voeg een klasse genaamd TodoTaggerProvider toe die ITaggerProvider implementeert en exporteer deze met een ContentTypeAttribute van 'code' en een TagTypeAttribute van TodoTag.

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

    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. Implementeer de CreateTagger methode door de TodoTaggermethode te instantiëren.

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

De code bouwen en testen

Als u deze code wilt testen, bouwt u de todoGlyphTest-oplossing en voert u deze uit in het experimentele exemplaar.

De TodoGlyphTest-oplossing bouwen en testen

  1. Bouw de oplossing.

  2. Voer het project uit door op F5 te drukken. Er wordt een tweede exemplaar van Visual Studio gestart.

  3. Zorg ervoor dat de indicatormarge wordt weergegeven.

    Controleer in het deelvenster Extra>Opties, onder de sectie Alle instellingen>Teksteditor>Algemeen>Weergave, of het selectievakje Indicatormarge weergeven is aangevinkt.

    Controleer in het dialoogvensterExtra-opties> onder de sectieAlgemeen>weergeven van > of het selectievakje Indicatormarge is ingeschakeld.

  4. Open een codebestand met opmerkingen. Voeg het woord 'todo' toe aan een van de opmerkingensecties.

  5. Er wordt een lichtblauwe cirkel met een donkerblauw kader weergegeven in de indicatormarge links van het codevenster.