Procédure pas à pas : Création d’un glyphe de margeWalkthrough: Creating a Margin Glyph

Vous pouvez personnaliser l’apparence des marges d’éditeur à l’aide des extensions de l’éditeur personnalisé.You can customize the appearance of editor margins by using custom editor extensions. Cette procédure pas à pas place un glyphe personnalisé sur la marge des indicateurs à chaque fois que le mot « todo » s’affiche dans un commentaire de code.This walkthrough puts a custom glyph on the indicator margin whenever the word "todo" appears in a code comment.

PrérequisPrerequisites

À partir de Visual Studio 2015, vous n’installez pas le Kit de développement logiciel Visual Studio à partir du centre de téléchargement.Starting in Visual Studio 2015, you do not install the Visual Studio SDK from the download center. Il est inclus comme une fonctionnalité facultative dans le programme d’installation de Visual Studio.It is included as an optional feature in Visual Studio setup. Vous pouvez également installer le kit SDK VS ultérieurement.You can also install the VS SDK later on. Pour plus d’informations, consultez l’installation de Visual Studio SDK.For more information, see Installing the Visual Studio SDK.

Création d’un projet MEFCreating a MEF Project

  1. Créez un projet VSIX c#.Create a C# VSIX project. (Dans le nouveau projet boîte de dialogue, sélectionnez Visual c# / extensibilité, puis projet VSIX.) Nommez la solution TodoGlyphTest.(In the New Project dialog, select Visual C# / Extensibility, then VSIX Project.) Name the solution TodoGlyphTest.

  2. Ajouter un élément de projet classifieur d’éditeur.Add an Editor Classifier project item. Pour plus d’informations, consultez création d’une Extension avec un éditeur de modèle d’élément.For more information, see Creating an Extension with an Editor Item Template.

  3. Supprimez les fichiers de classe existants.Delete the existing class files.

Définir le glypheDefining the Glyph

Définir un glyphe en implémentant le IGlyphFactory interface.Define a glyph by implementing the IGlyphFactory interface.

Pour définir le glypheTo define the glyph

  1. Ajoutez un fichier de classe et nommez-le TodoGlyphFactory.Add a class file and name it TodoGlyphFactory.

  2. Ajoutez le code suivant à l’aide des déclarations.Add the following using declarations.

    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;
    
    Imports System.ComponentModel.Composition
    Imports System.Windows
    Imports System.Windows.Shapes
    Imports System.Windows.Media
    Imports System.Windows.Controls
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Editor
    Imports Microsoft.VisualStudio.Text.Formatting
    Imports Microsoft.VisualStudio.Text.Tagging
    Imports Microsoft.VisualStudio.Utilities
    
  3. Ajoutez une classe nommée TodoGlyphFactory qui implémente IGlyphFactory.Add a class named TodoGlyphFactory that implements IGlyphFactory.

    internal class TodoGlyphFactory : IGlyphFactory
    
    Friend Class TodoGlyphFactory
        Implements IGlyphFactory
    
  4. Ajoutez un champ privé qui définit les dimensions du glyphe.Add a private field that defines the dimensions of the glyph.

    const double m_glyphSize = 16.0;
    
    Const m_glyphSize As Double = 16.0
    
  5. Implémentez GenerateGlyph en définissant l’élément d’interface utilisateur utilisateur glyphe.Implement GenerateGlyph by defining the glyph user interface (UI) element. TodoTag est défini plus loin dans cette procédure pas à pas.TodoTag is defined later in this walkthrough.

    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;
    }
    
    Public Function GenerateGlyph(ByVal line As IWpfTextViewLine, ByVal tag As IGlyphTag) As System.Windows.UIElement Implements IGlyphFactory.GenerateGlyph
        ' Ensure we can draw a glyph for this marker.
        If tag Is Nothing OrElse Not (TypeOf tag Is TodoTag) Then
            Return Nothing
        End If
    
        Dim ellipse As Ellipse = New Ellipse()
        ellipse.Fill = Brushes.LightBlue
        ellipse.StrokeThickness = 2
        ellipse.Stroke = Brushes.DarkBlue
        ellipse.Height = m_glyphSize
        ellipse.Width = m_glyphSize
    
        Return ellipse
    
    End Function
    
  6. Ajoutez une classe nommée TodoGlyphFactoryProvider qui implémente IGlyphFactoryProvider.Add a class named TodoGlyphFactoryProvider that implements IGlyphFactoryProvider. Exporter cette classe avec un NameAttribute de « TodoGlyph », un OrderAttribute d’après VsTextMarker, un ContentTypeAttribute de « code » et un TagTypeAttribute de TodoTag.Export this class with a NameAttribute of "TodoGlyph", an OrderAttribute of After VsTextMarker, a ContentTypeAttribute of "code", and a TagTypeAttribute of TodoTag.

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
    <Export(GetType(IGlyphFactoryProvider)), Name("TodoGlyph"), Order(After:="VsTextMarker"), ContentType("code"), TagType(GetType(TodoTag))>
    Friend NotInheritable Class TodoGlyphFactoryProvider
        Implements IGlyphFactoryProvider
    
  7. Implémentez la GetGlyphFactory méthode en instanciant le TodoGlyphFactory.Implement the GetGlyphFactory method by instantiating the TodoGlyphFactory.

    public IGlyphFactory GetGlyphFactory(IWpfTextView view, IWpfTextViewMargin margin)
    {
        return new TodoGlyphFactory();
    }
    
    Public Function GetGlyphFactory(ByVal view As IWpfTextView, ByVal margin As IWpfTextViewMargin) As IGlyphFactory Implements IGlyphFactoryProvider.GetGlyphFactory
        Return New TodoGlyphFactory()
    End Function
    

Définition d’une balise de tâches et de la baliseDefining a Todo Tag and Tagger

Définir la relation entre l’élément d’interface utilisateur que vous avez définie dans les étapes précédentes et la marge des indicateurs en créant un type de balise et la balise et exportant à l’aide d’un fournisseur de baliseur.Define the relationship between the UI element that you defined in the previous steps and the indicator margin by creating a tag type and tagger, and exporting it by using a tagger provider.

Pour définir une balise de tâches et de la baliseTo define a todo tag and tagger

  1. Ajouter un nouveau fichier de classe au projet et nommez-le TodoTagger.Add a new class file to the project and name it TodoTagger.

  2. Ajoutez les importations suivantes.Add the following imports.

    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;
    
    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel.Composition
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Tagging
    Imports Microsoft.VisualStudio.Text.Editor
    Imports Microsoft.VisualStudio.Text.Classification
    Imports Microsoft.VisualStudio.Utilities
    
  3. Ajoutez une classe nommée TodoTag.Add a class named TodoTag.

    internal class TodoTag : IGlyphTag
    
    Friend Class TodoTag
        Implements IGlyphTag
    
        Public Sub New()
            MyBase.New()
        End Sub
    End Class
    
  4. Modifiez la classe nommée TodoTagger qui implémente ITagger<T> de type TodoTag.Modify the class named TodoTagger that implements ITagger<T> of type TodoTag.

    internal class TodoTagger : ITagger<TodoTag>
    
    Friend Class TodoTagger
        Implements ITagger(Of TodoTag)
    
  5. Pour le TodoTagger (classe), ajoutez des champs privés pour un IClassifier et pour le texte à rechercher dans la classification s’étend.To the TodoTagger class, add private fields for an IClassifier and for the text to find in the classification spans.

    private IClassifier m_classifier;
    private const string m_searchText = "todo";
    
    Private m_classifier As IClassifier
    Private Const m_searchText As String = "todo"
    
  6. Ajoutez un constructeur qui définit le classifieur.Add a constructor that sets the classifier.

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
    Friend Sub New(ByVal classifier As IClassifier)
        m_classifier = classifier
    End Sub
    
  7. Implémentez la GetTags méthode en recherchant la classification de tous les couvre dont les noms incluent le mot « commentaire » et dont le texte contient le texte de recherche.Implement the GetTags method by finding all the classification spans whose names include the word "comment" and whose text includes the search text. Chaque fois que le texte de recherche est trouvé, revenir génère un nouveau TagSpan<T> de type TodoTag.Whenever the search text is found, yield back a new TagSpan<T> of 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());
                    }
                }
            }
        }
    }
    
    Private Function GetTags(ByVal spans As NormalizedSnapshotSpanCollection) As IEnumerable(Of ITagSpan(Of TodoTag)) Implements ITagger(Of TodoTag).GetTags
        Dim list As List(Of ITagSpan(Of TodoTag))
        list = New List(Of ITagSpan(Of TodoTag))()
    
        For Each span As SnapshotSpan In spans
            'look at each classification span \
            For Each classification As ClassificationSpan In m_classifier.GetClassificationSpans(span)
                'if the classification is a comment
                If classification.ClassificationType.Classification.ToLower().Contains("comment") Then
                    'if the word "todo" is in the comment,
                    'create a new TodoTag TagSpan
                    Dim index As Integer = classification.Span.GetText().ToLower().IndexOf(m_searchText)
                    If index <> -1 Then
                        list.Add(New TagSpan(Of TodoTag)(New SnapshotSpan(classification.Span.Start + index, m_searchText.Length), New TodoTag()))
                    End If
                End If
            Next classification
        Next span
    
        Return list
    End Function
    
  8. Déclarez un TagsChanged événement.Declare a TagsChanged event.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
    Public Event TagsChanged(ByVal sender As Object, ByVal e As Microsoft.VisualStudio.Text.SnapshotSpanEventArgs) Implements Microsoft.VisualStudio.Text.Tagging.ITagger(Of TodoTag).TagsChanged
    
  9. Ajoutez une classe nommée TodoTaggerProvider qui implémente ITaggerProvideret l’exporter avec un ContentTypeAttribute de « code » et un TagTypeAttribute de TodoTag.Add a class named TodoTaggerProvider that implements ITaggerProvider, and export it with a ContentTypeAttribute of "code" and a TagTypeAttribute of TodoTag.

    [Export(typeof(ITaggerProvider))]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    class TodoTaggerProvider : ITaggerProvider
    
    <Export(GetType(ITaggerProvider)), ContentType("code"), TagType(GetType(TodoTag))>
    Friend Class TodoTaggerProvider
        Implements ITaggerProvider
    
  10. Importer le IClassifierAggregatorService.Import the IClassifierAggregatorService.

    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
    <Import()>
    Friend AggregatorService As IClassifierAggregatorService
    
  11. Implémentez la CreateTagger méthode en instanciant le TodoTagger.Implement the CreateTagger method by instantiating the 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>;
    }
    
    Public Function CreateTagger(Of T As Microsoft.VisualStudio.Text.Tagging.ITag)(ByVal buffer As Microsoft.VisualStudio.Text.ITextBuffer) As Microsoft.VisualStudio.Text.Tagging.ITagger(Of T) Implements Microsoft.VisualStudio.Text.Tagging.ITaggerProvider.CreateTagger
        If buffer Is Nothing Then
            Throw New ArgumentNullException("buffer")
        End If
    
        Return TryCast(New TodoTagger(AggregatorService.GetClassifier(buffer)), ITagger(Of T))
    End Function
    

Création et test du codeBuilding and Testing the Code

Pour tester ce code, générez la solution TodoGlyphTest et l’exécuter dans l’instance expérimentale.To test this code, build the TodoGlyphTest solution and run it in the experimental instance.

Pour générer et tester la solution TodoGlyphTestTo build and test the TodoGlyphTest solution

  1. Générez la solution.Build the solution.

  2. Exécutez le projet en appuyant sur F5.Run the project by pressing F5. Une deuxième instance de Visual Studio est instanciée.A second instance of Visual Studio is instantiated.

  3. Assurez-vous que la marge des indicateurs s’affiche.Make sure that the indicator margin is showing. (Sur le outils menu, cliquez sur Options.(On the Tools menu, click Options. Dans le éditeur de texte , assurez-vous que marge des indicateurs est sélectionné.)On the Text Editor page, make sure that Indicator margin is selected.)

  4. Ouvrez un fichier de code qui a des commentaires.Open a code file that has comments. Ajoutez le mot « todo » à une des sections de commentaire.Add the word "todo" to one of the comment sections.

  5. Un cercle bleu clair qui a un contour bleu foncé doit apparaître dans la marge des indicateurs à gauche de la fenêtre de code.A light blue circle that has a dark blue outline should appear in the indicator margin to the left of the code window.