Passo a passo: Criando um glifo de margem
Você pode personalizar a aparência das margens do editor usando as extensões de editor personalizado. Este passo a passo coloca um glifo personalizado na margem indicadora sempre que a palavra "todo" é exibida em um comentário do código.
Pré-requisitos
Para concluir este passo a passo, você deve instalar o SDL do Visual Studio 2010.
Dica
Para obter mais informações sobre o SDK de Visual Studio, consulte Ampliando a visão geral de Visual Studio.Para descobrir como fazer o download do SDK do Visual Studio, consulte Visual Studio extensibilidade Developer Center no site do MSDN.
Criando um projeto do Framework (MEF) de extensibilidade gerenciada
Para criar um projeto MEF
Crie um projeto do Visual C# ou Visual Basic Editor classificador. Nomeie a solução TodoGlyphTest.
Abra o arquivo de Source.extension.vsixmanifest no Editor de VSIX de manifesto.
Certifique-se de que o Content título contém um tipo de conteúdo do componente MEF e que o Path for definido como TodoGlyphTest.dll.
Salve e feche o Source.extension.vsixmanifest.
Remova os arquivos de classe existentes.
Definindo o glifo.
Definir um glifo, Implementando o IGlyphFactory interface.
Para definir o glifo.
Adicione um arquivo de classe e denomine- TodoGlyphFactory.
Adicione as importações a seguintes.
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;
Adicionar uma classe chamada TodoGlyphFactory que implementa IGlyphFactory.
Friend Class TodoGlyphFactory Implements IGlyphFactory
internal class TodoGlyphFactory : IGlyphFactory
Adicione um campo privado que define as dimensões do glifo.
Const m_glyphSize As Double = 16.0
const double m_glyphSize = 16.0;
Implementar GenerateGlyph , definindo o elemento de interface (UI) do usuário de glifo. TodoTagé definida mais adiante neste passo a passo.
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; }
Adicionar uma classe chamada TodoGlyphFactoryProvider que implementa IGlyphFactoryProvider. Exportar essa classe com um NameAttribute de "TodoGlyph", um OrderAttribute de VsTextMarker de após um ContentTypeAttribute de "código" e um 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
Implementar a GetGlyphFactory método instanciando o 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(); }
Definição de uma marca de Todo e Tagger
Defina a relação entre o elemento de interface do usuário que você definiu nas etapas anteriores e a margem do indicador, criando um tipo de marca e tagger e, em seguida, exportá-la usando um provedor de tagger.
Para definir uma marca de todo e tagger
Adicione uma nova classe ao projeto e denomine- TodoTagger.
Adicione as importações a seguintes.
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;
Adicionar uma classe chamada TodoTag.
Friend Class TodoTag Implements IGlyphTag Public Sub New() MyBase.New() End Sub End Class
internal class TodoTag : IGlyphTag
Modificar a classe chamada TodoTagger que implementa ITagger do tipo TodoTag.
Friend Class TodoTagger Implements ITagger(Of TodoTag)
internal class TodoTagger : ITagger<TodoTag>
Para o TodoTagger classe, adicionar campos privados para um IClassifier e para o texto a ser localizado na classificação abrange.
Private m_classifier As IClassifier Private Const m_searchText As String = "todo"
private IClassifier m_classifier; private const string m_searchText = "todo";
Adicione um construtor que defina o classificador.
Friend Sub New(ByVal classifier As IClassifier) m_classifier = classifier End Sub
internal TodoTagger(IClassifier classifier) { m_classifier = classifier; }
Implementar a GetTags método encontrando todas a classificação abrange cujos nomes incluem a palavra "comentário" e cujo texto inclua o texto de pesquisa. Sempre que o texto de pesquisa for encontrado, volta gerar uma nova TagSpan do 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()); } } } } }
Declarar um TagsChanged evento.
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;
Adicionar uma classe chamada TodoTaggerProvider que implementa ITaggerProvidere exportá-lo com um ContentTypeAttribute de "código" e um 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
Importação de IClassifierAggregatorService.
<Import()> Friend AggregatorService As IClassifierAggregatorService
[Import] internal IClassifierAggregatorService AggregatorService;
Implementar a CreateTagger``1 método instanciando o 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>; }
Criar e testar o código
Para testar esse código, crie a solução de TodoGlyphTest e execute-o na instância experimental.
Para criar e testar a solução de TodoGlyphTest
Crie a solução.
Execute o projeto pressionando F5. Uma segunda instância do Visual Studio é instanciada.
Certifique-se de que a margem do indicador está mostrando. (Sobre o Ferramentas menu, clique em Opções de. Diante do Editor de texto de página, certifique-se de que margem do indicador está selecionada.)
Abra um arquivo de código tem comentários. Adicione a palavra "todo" para uma das seções de comentário.
Um círculo azul claro que tem um contorno azul escuro deve aparecer na margem indicadora à esquerda da janela de código.