共用方式為


逐步解說︰ 建立邊界圖像

 

如需 Visual Studio 2017 的最新文件請參閱 Visual Studio 2017 文件

使用自訂的編輯器延伸模組,您可以自訂編輯器邊界的外觀。 本逐步解說中放置自訂圖像的指標邊界,每當"todo"這個字出現在程式碼註解。

必要條件

啟動 Visual Studio 2015 中,您未安裝 Visual Studio SDK 從 「 下載中心 」。 它是 Visual Studio 安裝程式的選用功能。 您也可以在稍後安裝 VS SDK。 如需詳細資訊,請參閱安裝 Visual Studio SDK

建立 MEF 專案

  1. 建立 C# VSIX 專案。 (在新的專案對話方塊中,選取Visual C# / 擴充性,然後VSIX 專案。)將方案命名為TodoGlyphTest

  2. 加入分類編輯器專案項目。 如需詳細資訊,請參閱編輯器項目範本以建立副檔名為

  3. 刪除現有類別檔案。

定義圖像 (glyph)

藉由實作定義圖像 (glyph) IGlyphFactory介面。

若要定義圖像 (glyph)

  1. 將類別檔案,並將它TodoGlyphFactory

  2. 新增下列使用宣告。

    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;
    
    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
    
  3. 新增名為TodoGlyphFactory實作IGlyphFactory

    internal class TodoGlyphFactory : IGlyphFactory
    
    Friend Class TodoGlyphFactory
        Implements IGlyphFactory
    
  4. 加入私用欄位來定義維度的圖像。

        const double m_glyphSize = 16.0;
    
        Const m_glyphSize As Double = 16.0
    
  5. 實作GenerateGlyph藉由定義圖像 (glyph) 使用者介面 (UI) 項目。 TodoTag本逐步解說稍後定義。

        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;
        }
    
        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
    
  6. 新增名為TodoGlyphFactoryProvider實作IGlyphFactoryProvider。 匯出與這個類別NameAttribute的 「 TodoGlyph 」, OrderAttribute之後 VsTextMarker 的ContentTypeAttribute的 「 程式碼 」 和TagTypeAttribute TodoTag。

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
        <Export(GetType(IGlyphFactoryProvider)), Name("TodoGlyph"), Order(After:="VsTextMarker"), ContentType("code"), TagType(GetType(TodoTag))>
        Friend NotInheritable Class TodoGlyphFactoryProvider
            Implements IGlyphFactoryProvider
    
  7. 實作GetGlyphFactory方法具現化TodoGlyphFactory

        public IGlyphFactory GetGlyphFactory(IWpfTextView view, IWpfTextViewMargin margin)
        {
            return new TodoGlyphFactory();
        }
    
            Public Function GetGlyphFactory(ByVal view As IWpfTextView, ByVal margin As IWpfTextViewMargin) As IGlyphFactory Implements IGlyphFactoryProvider.GetGlyphFactory
                Return New TodoGlyphFactory()
            End Function
    

定義 Todo 標記與標註器

藉由建立標記型別與標註器,並將它匯出使用標註器提供者定義的指標邊界,在先前步驟中所定義的 UI 項目之間的關聯性。

若要定義 todo 標記和標註器

  1. 將新的類別檔案加入至專案,並將它TodoTagger

  2. 新增下列匯入。

    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;
    
    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
    
  3. 新增名為TodoTag

    internal class TodoTag : IGlyphTag
    
    Friend Class TodoTag
        Implements IGlyphTag
    
        Public Sub New()
            MyBase.New()
        End Sub
    End Class
    
  4. 修改類別,名為TodoTagger實作ITagger<> </> >型別的TodoTag

    internal class TodoTagger : ITagger<TodoTag>
    
    Friend Class TodoTagger
        Implements ITagger(Of TodoTag)
    
  5. 若要TodoTagger類別中,加入私用欄位IClassifier和文字,以在該分類中找到跨越。

        private IClassifier m_classifier;
        private const string m_searchText = "todo";
    
        Private m_classifier As IClassifier
        Private Const m_searchText As String = "todo"
    
  6. 新增設定分類器的建構函式。

        internal TodoTagger(IClassifier classifier)
        {
            m_classifier = classifier;
        }
    
        Friend Sub New(ByVal classifier As IClassifier)
            m_classifier = classifier
        End Sub
    
  7. 實作GetTags方法藉由尋找所有分類涵蓋其名稱包含單字"註解 」,以及其文字包含搜尋文字。 找到搜尋文字,只要重新產生新TagSpan<> </> >型別的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());
                        }
                    }
                }
            }
        }
    
        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
    
  8. 宣告TagsChanged事件。

        public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
        Public Event TagsChanged(ByVal sender As Object, ByVal e As Microsoft.VisualStudio.Text.SnapshotSpanEventArgs) Implements Microsoft.VisualStudio.Text.Tagging.ITagger(Of TodoTag).TagsChanged
    
  9. 新增名為TodoTaggerProvider實作ITaggerProvider,並將它與匯出ContentTypeAttribute的 「 程式碼 」 和TagTypeAttribute TodoTag。

    [Export(typeof(ITaggerProvider))]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    class TodoTaggerProvider : ITaggerProvider
    
    <Export(GetType(ITaggerProvider)), ContentType("code"), TagType(GetType(TodoTag))>
    Friend Class TodoTaggerProvider
        Implements ITaggerProvider
    
  10. 匯入IClassifierAggregatorService

        [Import]
        internal IClassifierAggregatorService AggregatorService;
    
        <Import()>
        Friend AggregatorService As IClassifierAggregatorService
    
  11. 實作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>;
        }
    
        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
    

建置和測試程式碼

若要測試這段程式碼,TodoGlyphTest 方案中建置並執行它的實驗執行個體。

若要建置和測試 TodoGlyphTest 方案

  1. 建置方案。

  2. 按 F5 執行專案。 Visual Studio 的第二個執行個體具現化。

  3. 請確定會顯示指標邊界。 (在工具] 功能表上,按一下 [選項。 在文字編輯器頁面上,請確定指標邊界已選取。)

  4. 開啟有註解的程式碼檔案。 將"todo"這個字加入至其中一個註解區段。

  5. 深藍色外框的淺藍色圓形應該會出現在左邊的 [程式碼] 視窗的指標邊界。