逐步解說:建立邊界圖像

您可以使用自訂編輯器擴充功能來自訂編輯器邊界的外觀。 本逐步解說會在程式碼註釋中出現「todo」 這個字時,將自訂圖像放在指示區邊界上。

建立 MEF 專案

  1. 建立 C# VXIS 專案。 (在新增專案對話框中,選取 Visual C# /擴充性,然後選取 VSIX 專案。) 命名解決方案 TodoGlyphTest

  2. 新增編輯器分類器專案項目。 如需詳細資訊,請參閱 使用編輯器項目範本建立擴充功能

  3. 刪除現有類別檔案。

定義圖像

執行 IGlyphFactory 介面來定義圖像。

定義圖像

  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;
    
  3. 新增名為 TodoGlyphFactory 且實作 IGlyphFactory 的類別。

    internal class TodoGlyphFactory : IGlyphFactory
    
  4. 新增可定義圖像維度的私有欄位。

    const double m_glyphSize = 16.0;
    
  5. 藉由定義圖像使用者介面 (UI) 元素來實作 GenerateGlyphTodoTag 稍後會在此逐步解說中定義。

    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. 新增名為 TodoGlyphFactoryProvider 且實作 IGlyphFactoryProvider 的類別。 使用「TodoGlyph」的 NameAttribute、 After VsTextMarker 的OrderAttribute、「code」的 ContentTypeAttribute 和 TodoTag 的 TagTypeAttribute 匯出此類別。

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
  7. 藉由具現化 TodoGlyphFactory 來實作 GetGlyphFactory 方法。

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

定義 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;
    
  3. 新增名為 TodoTag 的類別。

    internal class TodoTag : IGlyphTag
    
  4. 修改名為 TodoTagger 的類別,其實作類型為 TodoTagITagger<T>

    internal class TodoTagger : ITagger<TodoTag>
    
  5. TodoTagger 類別中,新增 IClassifier 和文字的的私有欄位,以在分類範圍中尋找文字。

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

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. 尋找名稱包含「註釋」一詞且文字包含搜尋文字的所有分類範圍,以實作 GetTags 方法。 每當找到搜尋文字時,返回類型 TodoTag 的新 TagSpan<T>

    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. 宣告 TagsChanged事件。

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. 新增名為 TodoTaggerProvider 的類別,該類別實作 ITaggerProvider,並使用「code」的ContentTypeAttribute 和 TodoTag 的 TagTypeAttribute 將其匯出。

    [Export(typeof(ITaggerProvider))]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    class TodoTaggerProvider : ITaggerProvider
    
  10. 匯入 IClassifierAggregatorService

    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. 藉由具現化 TodoTagger 來實作 CreateTagger 方法。

    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 方案

  1. 建置方案。

  2. F5 執行專案。 Visual Studio 的第二個執行個體開啟。

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

  4. 開啟具有註釋的程式碼檔案。 將「todo」一詞新增至其中一個註釋區段。

  5. 深藍色外框的淺藍色圓圈會出現在程式碼視窗左邊的指示區邊界中。