Condividi tramite


procedura dettagliata: Creare un glifo del margine

È possibile personalizzare l'aspetto dei margini dell'editor utilizzando le estensioni editor personalizzato. In questa procedura dettagliata viene inserito un glifo personalizzato nel margine indicatore ogni volta che la parola “todo„ viene visualizzato in un commento del codice.

Prerequisiti

Per completare questa procedura dettagliata, è necessario installare Visual Studio 2010 SDK.

Nota

per ulteriori informazioni su Visual Studio SDK, vedere Cenni preliminari sull'estensione di Visual Studio.Per ulteriori informazioni su come scaricare Visual Studio SDK, vedere Centro per sviluppatori di estensibilità di Visual Studio il sito Web MSDN.

Creare un progetto gestito Framework (MEF) di estensibilità

Per creare un progetto MEF

  1. Creare un Visual c# o un progetto di classificatore di Visual Basic Editor. Assegnare alla soluzione TodoGlyphTest.

  2. Aprire il file Source.extension.vsixmanifest nell'editor del manifesto VSIX.

  3. Assicurarsi che la direzione di Content contenga un tipo di contenuto componente MEF e che Path è impostato su TodoGlyphTest.dll.

  4. salvare e chiudere Source.extension.vsixmanifest.

  5. Rimuovere i file di classe esistenti.

Definizione del glifo

definire un glifo implementando l'interfaccia di IGlyphFactory .

Per definire il glifo

  1. Aggiungere il file di classe e denominarlo TodoGlyphFactory.

  2. Aggiungere i seguenti elementi importati.

    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. Aggiungere TodoGlyphFactory classe denominata che implementa IGlyphFactory.

    Friend Class TodoGlyphFactory
        Implements IGlyphFactory
    
    internal class TodoGlyphFactory : IGlyphFactory
    
  4. Aggiungere un campo privato che definisce le dimensioni del glifo.

    Const m_glyphSize As Double = 16.0
    
    const double m_glyphSize = 16.0;
    
  5. Utilizzo GenerateGlyph definendo l'elemento dell'interfaccia utente del (UI) glifo. TodoTag definito più avanti in questa procedura dettagliata.

    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. Aggiungere TodoGlyphFactoryProvider classe denominata che implementa IGlyphFactoryProvider. Esportare questa classe con NameAttribute “di TodoGlyph„, OrderAttribute dopo di VsTextMarker, ContentTypeAttribute “del codice„ e TagTypeAttribute di 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. implementare il metodo di GetGlyphFactory creare un'istanza 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();
    }
    

Definizione di un tag e del Tagger di Todo

Definire la relazione tra l'elemento dell'interfaccia utente che è definito nei passaggi precedenti e nel margine indicatore creazione di un tipo e un tagger del tag e è utilizzando un provider di tagger.

Per definire un tag e un tagger di todo

  1. Aggiungere una nuova classe al progetto e denominarla TodoTagger.

  2. Aggiungere i seguenti elementi importati.

    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. Aggiungere TodoTagclasse denominata.

    Friend Class TodoTag
        Implements IGlyphTag
    
        Public Sub New()
            MyBase.New()
        End Sub 
    End Class
    
    internal class TodoTag : IGlyphTag
    
  4. modificare la classe denominata TodoTagger che implementa ITagger di tipo TodoTag.

    Friend Class TodoTagger
        Implements ITagger(Of TodoTag)
    
    internal class TodoTagger : ITagger<TodoTag>
    
  5. Alla classe di TodoTagger , aggiungere campi privati per IClassifier e per il testo da includere nella ricerca in intervalli di classificazione.

    Private m_classifier As IClassifier
    Private Const m_searchText As String = "todo"
    
    private IClassifier m_classifier;
    private const string m_searchText = "todo";
    
  6. Aggiungere un costruttore che imposta il classificatore.

    Friend Sub New(ByVal classifier As IClassifier)
        m_classifier = classifier
    End Sub
    
    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. Implementare il metodo di GetTags cercando tutti gli intervalli di classificazione dei nomi includono la parola “commento„ e il cui testo è incluso il testo cercato. Ogni volta che il testo cercato viene trovato, impostare di nuovo TagSpan di tipo 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. dichiarare un evento di 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. Aggiungere TodoTaggerProvider classe denominata che implementa ITaggerProvidere esportarlo con ContentTypeAttribute “del codice„ e TagTypeAttribute di 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. Importare IClassifierAggregatorService.

    <Import()>
    Friend AggregatorService As IClassifierAggregatorService
    
    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. implementare il metodo di CreateTagger``1 creare un'istanza 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>;
    }
    

Compilazione e test del codice

Per testare questo codice, compilare la soluzione di TodoGlyphTest ed eseguirla nell'istanza sperimentale.

Per compilare e testare la soluzione di TodoGlyphTest

  1. Compilare la soluzione.

  2. Premere F5 per eseguire il progetto. Una seconda istanza di Visual Studio viene creata un'istanza.

  3. Assicurarsi che il margine indicatore venga visualizzata. Dal menu di strumenti , fare clic su opzioni. Nella pagina di editor di testo , assicurarsi che margine indicatore sia selezionato.)

  4. Aprire un file di codice con commenti. Aggiungere la parola “todo„ a una delle sezioni di commento.

  5. Un cerchio blu-chiaro con una struttura blu scuro deve essere contenuto nel margine indicatore a sinistra della finestra del codice.