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. Cette procédure 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 le 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 en GenerateGlyph définissant l’élément d’interface utilisateur (IU) glyphe. 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 d’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 balisage

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 balisage

  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> le type TodoTag.

    internal class TodoTagger : ITagger<TodoTag>
    
  5. Dans la TodoTagger classe, ajoutez des champs privés pour un IClassifier texte à rechercher 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é, retournez un nouveau TagSpan<T> 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 « code » et un TagTypeAttribute todoTag.

    [Export(typeof(ITaggerProvider))]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    class TodoTaggerProvider : ITaggerProvider
    
  10. Importez 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. (Sur le Menu Outils, cliquez sur Options. Dans la page Éditeur de texte, vérifiez que la marge d’indicateur est sélectionné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.