Partilhar via


Demonstra Passo a passo: Criar um glifo de margem

Você pode personalizar a aparência das margens do editor usando extensões de editor personalizadas. Este passo a passo coloca um glifo personalizado na margem do indicador sempre que a palavra "todo" aparece em um comentário de código.

Criar um projeto MEF

  1. Crie um projeto C# VSIX. (No Caixa de diálogo Novo Projeto, selecione Visual C# / Extensibilidade e, em seguida, Projeto VSIX.) Nomeie a solução TodoGlyphTest.

  2. Adicione um item de projeto Editor Classificador. Para obter mais informações, consulte Criar uma extensão com um modelo de item do editor.

  3. Exclua os arquivos de classe existentes.

Definir o glifo

Defina um glifo executando a IGlyphFactory interface.

Para definir o glifo

  1. Adicione um arquivo de classe e nomeie-o TodoGlyphFactory.

  2. Adicione o código a seguir usando declarações.

    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. Adicione uma classe chamada TodoGlyphFactory que implementa IGlyphFactoryo .

    internal class TodoGlyphFactory : IGlyphFactory
    
  4. Adicione um campo privado que defina as dimensões do glifo.

    const double m_glyphSize = 16.0;
    
  5. Implemente GenerateGlyph definindo o elemento da interface do usuário (UI) do glifo. TodoTag é definido posteriormente nesta explicação passo a passo.

    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. Adicione uma classe chamada TodoGlyphFactoryProvider que implementa IGlyphFactoryProvidero . Exporte essa classe com um de "TodoGlyph", um de After VsTextMarker, um de "code" e um NameAttribute OrderAttribute ContentTypeAttribute TagTypeAttribute de TodoTag.

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
  7. Implemente o método instanciando o GetGlyphFactory TodoGlyphFactory.

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

Definir uma tag e um tagger Todo

Defina a relação entre o elemento da interface do usuário que você definiu nas etapas anteriores e a margem do indicador. Crie um tipo de tag e um tagger e exporte-o usando um provedor de tagger.

Para definir uma tag todo e um tagger

  1. Adicione um novo arquivo de classe ao projeto e nomeie-o TodoTagger.

  2. Adicione as seguintes importações.

    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. Adicione uma classe chamada TodoTag.

    internal class TodoTag : IGlyphTag
    
  4. Modifique a classe chamada TodoTagger que implementa ITagger<T> do tipo TodoTag.

    internal class TodoTagger : ITagger<TodoTag>
    
  5. Para a TodoTagger classe, adicione campos particulares para um IClassifier e para o texto localizar nas extensões de classificação.

    private IClassifier m_classifier;
    private const string m_searchText = "todo";
    
  6. Adicione um construtor que defina o classificador.

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. Implemente o método localizando todas as extensões de classificação cujos nomes incluem a palavra "comentário" e cujo texto inclui o GetTags texto de pesquisa. Sempre que o texto de pesquisa for encontrado, retorne um novo TagSpan<T> tipo 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. Declare um TagsChanged evento.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Adicione uma classe chamada TodoTaggerProvider que implementa ITaggerProvidero e exporte-a com um de "código" e um ContentTypeAttribute TagTypeAttribute de TodoTag.

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

    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. Implemente o método instanciando o CreateTagger 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>;
    }
    

Compilar e testar o código

Para testar esse código, compile a solução TodoGlyphTest e execute-a na instância experimental.

Para criar e testar a solução TodoGlyphTest

  1. Compile a solução.

  2. Execute o projeto pressionando F5. Uma segunda instância do Visual Studio é iniciada.

  3. Certifique-se de que a margem do indicador está sendo exibida. (Sobre o Menu Ferramentas, clique em Opções. Na página Editor de Texto, verifique se a opção Margem do indicador está selecionada.)

  4. Abra um arquivo de código que tenha comentários. Adicione a palavra "todo" a uma das seções de comentários.

  5. Um círculo azul claro com um contorno azul escuro aparece na margem do indicador à esquerda da janela de código.