Compartilhar via


Passo a passo: criar um glifo de margem

Você pode personalizar a aparência das margens do editor usando extensões personalizadas do editor. 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 do MEF

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

  2. Adicionar um item de projeto do Classificador de Editor. 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 IGlyphFactory.

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

    const double m_glyphSize = 16.0;
    
  5. Implemente GenerateGlyph definindo o elemento de interface do usuário do glifo. TodoTag é definido posteriormente neste 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 IGlyphFactoryProvider. Exporte esta classe com um NameAttribute de "TodoGlyph", um OrderAttribute de After VsTextMarker, um ContentTypeAttribute de "code" e um TagTypeAttribute de TodoTag.

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

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

Definir uma tag Todo e um marcador

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

Para definir uma etiqueta de tarefas e uma ferramenta de marcação

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

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

    internal class TodoTagger : ITagger<TodoTag>
    
  5. Para a classe TodoTagger, adicione campos privados para IClassifier e para o texto a ser localizado nos intervalos de classificação.

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

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. Implemente o GetTags método encontrando todos os intervalos de classificação cujos nomes incluem a palavra "comentário" e cujo texto inclui o texto de pesquisa. Sempre que o texto da 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 evento TagsChanged.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Adicione uma classe nomeada TodoTaggerProvider que implementa ITaggerProvider, e exporte-a com um ContentTypeAttribute "código" e um TagTypeAttribute 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 CreateTagger instanciando o 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, crie a solução TodoGlyphTest e execute-a na instância experimental.

Para criar e testar a solução TodoGlyphTest

  1. Crie a solução.

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

  3. Verifique se a margem do indicador está sendo exibida.

    No painel Ferramentas >Opções, na seção Texto > Editor >Geral >Exibição de Todas as Configurações, confirme se a caixa de seleção Mostrar margem de indicador está selecionada.

    Na caixa de diálogo Ferramentas>Opções, na seção Editor de Texto>Geral>Exibição, confirme se a caixa de seleção margem de indicador está marcada.

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

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