使用自定义编辑器扩展,您可以自定义编辑器边距外观。 本演练演示在指示器边距将自定义的标志符号,只要单词 “todo”显示代码注释。
系统必备
若要完成本演练,您必须安装 Visual Studio 2010 SDK。
备注
有关 Visual Studio SDK 的更多信息,请参见 扩展 Visual Studio 概述。若要查找有关中所列如何下载 Visual Studio SDK,请 Visual Studio Extensibility Developer Center 参见 MSDN 网站上。
创建一个 managed extensibility framework 项目 (MEF)
创建 MEF 项目
创建 Visual c# 或 Visual Basic 编辑器分类器项目。 将解决方案命名为 TodoGlyphTest。
打开在 VSIX 清单编辑器中的 Source.extension.vsixmanifest 文件。
确保 Content 归为包含一个 MEF 组件内容类型,而 Path 设置为 TodoGlyphTest.dll。
保存并关闭的 Source.extension.vsixmanifest。
删除现有类文件。
定义标志符号
通过实现 IGlyphFactory 接口定义标志符号。
定义标志符号
将类文件并将其命名为 TodoGlyphFactory。
添加下面的导入。
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;
添加类被命名为该 TodoGlyphFactory 实现 IGlyphFactory。
Friend Class TodoGlyphFactory Implements IGlyphFactory
internal class TodoGlyphFactory : IGlyphFactory
添加定义标志符号的维度的私有字段。
Const m_glyphSize As Double = 16.0
const double m_glyphSize = 16.0;
通过定义标志符号用户界面元素实现 (UI) GenerateGlyph 。 TodoTag 在本演练的稍后部分中定义。
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; }
添加类被命名为该 TodoGlyphFactoryProvider 实现 IGlyphFactoryProvider。 导出与 “TodoGlyph” NameAttribute ,在 VsTextMarker 后 OrderAttribute , “代码” ContentTypeAttribute 和 TodoTag TagTypeAttribute 的此类。
<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
通过实例化 TodoGlyphFactory执行 GetGlyphFactory 方法。
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(); }
定义 Todo 标记和标记
定义在前面的步骤和指示器边距定义通过创建标记类型和标记的 UI 元素和导出它之间的关系通过使用标记提供程序。
定义 todo 标记和标记
添加新类添加到项目并将其命名为 TodoTagger。
添加下面的导入。
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;
将名为 TodoTag的类。
Friend Class TodoTag Implements IGlyphTag Public Sub New() MyBase.New() End Sub End Class
internal class TodoTag : IGlyphTag
修改类被命名为该 TodoTagger 类型 TodoTag的实现 ITagger 。
Friend Class TodoTagger Implements ITagger(Of TodoTag)
internal class TodoTagger : ITagger<TodoTag>
为 TodoTagger 类中,添加私有字段 IClassifier 的且该文本的外观在类范围。
Private m_classifier As IClassifier Private Const m_searchText As String = "todo"
private IClassifier m_classifier; private const string m_searchText = "todo";
添加一组分类器的构造函数。
Friend Sub New(ByVal classifier As IClassifier) m_classifier = classifier End Sub
internal TodoTagger(IClassifier classifier) { m_classifier = classifier; }
通过查找名称中包含单词 “注释”,并包含的文本搜索文本的所有类范围执行 GetTags 方法。 只要找到搜索文本,请在给定类型 TodoTag新 TagSpan 。
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()); } } } } }
声明 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;
添加实现 ITaggerProvider名为 TodoTaggerProvider 的类,并将其导出与 “代码” ContentTypeAttribute 和 TodoTag TagTypeAttribute 。
<Export(GetType(ITaggerProvider)), ContentType("code"), TagType(GetType(TodoTag))> Friend Class TodoTaggerProvider Implements ITaggerProvider
[Export(typeof(ITaggerProvider))] [ContentType("code")] [TagType(typeof(TodoTag))] class TodoTaggerProvider : ITaggerProvider
导入 IClassifierAggregatorService。
<Import()> Friend AggregatorService As IClassifierAggregatorService
[Import] internal IClassifierAggregatorService AggregatorService;
通过实例化 TodoTagger执行 CreateTagger``1 方法。
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>; }
生成并测试代码
若要测试此代码,请生成 TodoGlyphTest 解决方案并运行在的实验实例。
生成和测试 TodoGlyphTest 解决方案
生成解决方案。
通过按 F5 键运行项目。 Visual Studio 的第二个实例进行实例化。
确保指示器边距显示。 (在 工具 菜单上,单击 选项。 在 文本编辑器 页上,确保 指示器边距 已选中。)
打开包含注释的代码文件。 添加单词 “todo”某个批注部分。
有一个后者一个轮廓浅蓝色的圆形应出现在指示器边距在代码窗口左侧。