Partilhar via


Guia: Crie um glifo de margem

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

Criar um projeto MEF

  1. Cria um projeto C# VSIX. (No diálogo Novo Projeto , selecione Visual C# / Extensibilidade, depois Projeto VSIX.) Diz a solução TodoGlyphTest.

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

  3. Apague os ficheiros de classe existentes.

Defina o glifo

Defina um glifo ao executar a IGlyphFactory interface.

Para definir o glifo

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

  2. Adicione o seguinte código 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 implemente IGlyphFactory.

    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 de interface de utilizador (UI) do glifo. TodoTag é definido mais adiante neste 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;
    }
    
  6. Adicione uma classe chamada TodoGlyphFactoryProvider que implemente 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 instanciando o TodoGlyphFactory.

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

Defina uma etiqueta Todo e um etiquetador

Defina a relação entre o elemento UI que definiu nos passos anteriores e a margem do indicador. Cria um tipo de etiqueta e um etiquetador e exporta-os usando um fornecedor de etiquetas.

Definir uma etiqueta de tarefa e um tagueador

  1. Adicione um novo ficheiro 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. Modificar a classe nomeada TodoTagger que implementa ITagger<T> do tipo TodoTag.

    internal class TodoTagger : ITagger<TodoTag>
    
  5. À classe TodoTagger, adicione campos privados para um IClassifier e para o texto a encontrar nos intervalos 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 GetTags método encontrando todos os intervalos de classificação cujos nomes incluem a palavra "comentário" e cujo texto inclui o texto da pesquisa. Sempre que o texto da pesquisa for encontrado, retorna um novo TagSpan<T> de 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. Declarar um evento TagsChanged.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Adicione uma classe chamada TodoTaggerProvider que implemente ITaggerProvider, e exporte-a com um ContentTypeAttribute de "code" e um 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 CreateTagger método 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>;
    }
    

Construir e testar o código

Para testar este código, constrói a solução TodoGlyphTest e executa-a na instância experimental.

Para construir e testar a solução TodoGlyphTest

  1. Crie a solução.

  2. Executa o projeto pressionando F5. Começa uma segunda instância do Visual Studio.

  3. Certifica-se de que a margem do indicador está visível.

    No painel Opções>Ferramentas, na secção Todas as Definições>, Editor de Texto>, Geral>, Visualização, confirme que a caixa de seleção Mostrar margem do indicador está selecionada.

    No diálogoFerramentas>Opções, na secçãoEditor de Texto>>, confirme que a caixa de seleção da margem do Indicador está selecionada.

  4. Abre um ficheiro de código com comentários. Adicione a palavra "todo" a uma das secçõ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.