Partager via


Procédure pas à pas : créer un glyphe de marge

Vous pouvez personnaliser l’apparence des marges de l’éditeur à l’aide d’extensions d’éditeur personnalisées. Ce guide pas à pas place un glyphe personnalisé sur la marge d’indicateur chaque fois que le mot « todo » apparaît dans un commentaire de code.

Créer un projet MEF

  1. Créez un projet VSIX C#. (Dans la boîte de dialogue Nouveau projet , sélectionnez Visual C# / Extensibilité, puis VSIX Project.) Nommez la solution TodoGlyphTest.

  2. Ajoutez un élément de projet Classifieur d’éditeur. Pour plus d’informations, consultez Créer une extension avec un modèle d’élément d’éditeur.

  3. Supprimez les fichiers de classe existants.

Définir le glyphe

Définissez un glyphe en exécutant l’interface IGlyphFactory .

Pour définir le glyphe

  1. Ajoutez un fichier de classe et nommez-le TodoGlyphFactory.

  2. Ajoutez le code suivant à l’aide de déclarations.

    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. Ajoutez une classe nommée TodoGlyphFactory qui implémente IGlyphFactory.

    internal class TodoGlyphFactory : IGlyphFactory
    
  4. Ajoutez un champ privé qui définit les dimensions du glyphe.

    const double m_glyphSize = 16.0;
    
  5. Implémentez GenerateGlyph en définissant l’élément de glyphe de l’interface utilisateur. TodoTag est défini plus loin dans cette procédure pas à pas.

    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. Ajoutez une classe nommée TodoGlyphFactoryProvider qui implémente IGlyphFactoryProvider. Exportez cette classe avec un NameAttribute « TodoGlyph », un OrderAttribute de type Après VsTextMarker, un ContentTypeAttribute « code » et un TagTypeAttribute de TodoTag.

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
  7. Implémentez la GetGlyphFactory méthode en instanciant le TodoGlyphFactory.

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

Définir une balise Todo et un tagger

Définissez la relation entre l’élément d’interface utilisateur que vous avez défini dans les étapes précédentes et la marge d’indicateur. Créez un type d’étiquette et un balisage et exportez-le à l’aide d’un fournisseur d’étiquettes.

Pour définir une balise todo et un marqueur

  1. Ajoutez un nouveau fichier de classe au projet et nommez-le TodoTagger.

  2. Ajoutez les importations suivantes.

    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. Ajoutez une classe nommée TodoTag.

    internal class TodoTag : IGlyphTag
    
  4. Modifiez la classe nommée TodoTagger qui implémente ITagger<T> de type TodoTag.

    internal class TodoTagger : ITagger<TodoTag>
    
  5. Dans la classe TodoTagger, ajoutez des champs privés pour un IClassifier et pour le texte à trouver dans les étendues de classification.

    private IClassifier m_classifier;
    private const string m_searchText = "todo";
    
  6. Ajoutez un constructeur qui définit le classifieur.

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. Implémentez la GetTags méthode en recherchant toutes les étendues de classification dont les noms incluent le mot « commentaire » et dont le texte inclut le texte de recherche. Chaque fois que le texte de recherche est trouvé, générez un nouveau TagSpan<T> de type 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. Déclarez un TagsChanged événement.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Ajoutez une classe nommée TodoTaggerProvider qui implémente ITaggerProvider, puis exportez-la avec un ContentTypeAttribute de « code » et un TagTypeAttribute de TodoTag.

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

    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. Implémentez la CreateTagger méthode en instanciant le 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>;
    }
    

Générer et tester le code

Pour tester ce code, générez la solution TodoGlyphTest et exécutez-la dans l’instance expérimentale.

Pour générer et tester la solution TodoGlyphTest

  1. Générez la solution.

  2. Exécutez le projet en appuyant sur F5. Une deuxième instance de Visual Studio démarre.

  3. Vérifiez que la marge d’indicateur s’affiche.

    Dans le volet Outils>Options, sous la section Tous les paramètres> Général>, vérifiez que la case à cocher Afficher la marge d’indicateur est cochée.

    Dans la boîte de dialogueOptions>, sous la sectionAffichage> de > de texte, vérifiez que la case à cocher Marge de l’indicateur est cochée.

  4. Ouvrez un fichier de code contenant des commentaires. Ajoutez le mot « todo » à l’une des sections de commentaire.

  5. Un cercle bleu clair avec un contour bleu foncé apparaît dans la marge d’indicateur à gauche de la fenêtre de code.