Partager via


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

Vous pouvez personnaliser l'apparence des marges d'éditeur en utilisant des extensions personnalisées d'éditeur. Cette procédure pas - à - pas place un glyphe personnalisé dans la marge des indicateurs chaque fois que le mot « todo » s'affiche dans un commentaire de code.

Composants requis

Pour exécuter cette procédure, vous devez installer Kit de développement logiciel Visual Studio 2010.

Notes

Pour plus d'informations sur le kit de développement Visual Studio, consultez Étendre la présentation de Visual Studio.Pour savoir comment télécharger le kit de développement Visual Studio, consultez Visual Studio Extensibility Developer Center sur le site Web MSDN.

Créer un projet managé (MEF) managed extensibility framework

Pour créer un projet MEF

  1. Créez un Visual c# ou un projet de classifieur Visual Basic Editor. nommez la solution TodoGlyphTest.

  2. Ouvrez le fichier Source.extension.vsixmanifest dans l'éditeur de manifeste VSIX.

  3. Assurez -vous que le titre d' Content contient un type de contenu composant MEF et qu' Path est défini à TodoGlyphTest.dll.

  4. Enregistrez et fermez le fichier Source.extension.vsixmanifest.

  5. supprimez les fichiers de classe existants.

définir le glyphe

définissez un glyphe en implémentant l'interface d' IGlyphFactory .

pour définir le glyphe

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

  2. Ajoutez les importations ci-après.

    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
    
    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.

    Friend Class TodoGlyphFactory
        Implements IGlyphFactory
    
    internal class TodoGlyphFactory : IGlyphFactory
    
  4. Ajoutez un champ privé qui définit les dimensions de glyphe.

    Const m_glyphSize As Double = 16.0
    
    const double m_glyphSize = 16.0;
    
  5. implémentez GenerateGlyph en définissant l'élément de l'interface utilisateur de glyphe (UI). TodoTag est défini à une étape ultérieure de cette procédure.

    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
    
    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 NameAttribute « TodoGlyph », OrderAttribute de après VsTextMarker, ContentTypeAttribute « code », et TagTypeAttribute de TodoTag.

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

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

Définir une balise et un balises de Todo

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 des indicateurs en créant un type et un balises de balise, et l'exporter à l'aide d'un fournisseur de balises.

Pour définir une balise et un balises de todo

  1. Ajoutez une nouvelle classe au projet et nommez TodoTagger.

  2. Ajoutez les importations ci-après.

    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
    
    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.

    Friend Class TodoTag
        Implements IGlyphTag
    
        Public Sub New()
            MyBase.New()
        End Sub 
    End Class
    
    internal class TodoTag : IGlyphTag
    
  4. modifiez la classe nommée TodoTagger qui implémente ITagger de type TodoTag.

    Friend Class TodoTagger
        Implements ITagger(Of TodoTag)
    
    internal class TodoTagger : ITagger<TodoTag>
    
  5. À la classe d' TodoTagger , ajoutez des champs privés pour IClassifier et du texte le recherche dans les étendues de classification.

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

    Friend Sub New(ByVal classifier As IClassifier)
        m_classifier = classifier
    End Sub
    
    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. Implémentez la méthode d' GetTags en recherchant toutes les étendues de classification desquels les noms comprennent le mot « commentaire » et dont le texte inclut le texte d'entrée. Chaque fois que le texte de recherche est trouvé, générer arrière nouvel TagSpan de type 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
    
    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 événement d' TagsChanged .

    Public Event TagsChanged(ByVal sender As Object, ByVal e As Microsoft.VisualStudio.Text.SnapshotSpanEventArgs) Implements Microsoft.VisualStudio.Text.Tagging.ITagger(Of TodoTag).TagsChanged
    
    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Ajoutez une classe nommée TodoTaggerProvider qui implémente ITaggerProvider, et exportez-la avec ContentTypeAttribute « code » et TagTypeAttribute de TodoTag.

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

    <Import()>
    Friend AggregatorService As IClassifierAggregatorService
    
    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. Implémentez la méthode d' CreateTagger``1 en instanciant TodoTagger.

    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
    
    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ération et test de code

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

Pour générer et tester la solution de TodoGlyphTest

  1. Générez la solution.

  2. Exécutez le projet en appuyant sur F5. une deuxième instance de Visual Studio est instanciée.

  3. Assurez -vous que la marge des indicateurs affiche. (Dans le menu d' Outils , cliquez sur Options. sur la page d' Éditeur de texte , assurez-vous que Marge des indicateurs est sélectionné.)

  4. Ouvrez un fichier de code qui comporte des commentaires. Ajoutez le mot « todo » à l'une des sections commentaires.

  5. Un cercle bleu clair qui a un plan bleu-foncé doit apparaître dans la marge des indicateurs à gauche de la fenêtre de code.