共用方式為


逐步解說: 反白顯示文字

您可以新增到編輯器] 中的不同的視覺效果,藉由建立管理擴充性架構 (MEF) 元件組件。 這個逐步解說會示範如何反白顯示每次出現的文字檔案中目前的文字。 如果 word 在 [文字檔案時,發生一次以上,您將插入號放在一個發生點,每個項目會反白顯示。

必要條件

若要完成這個逐步解說中,您必須安裝Visual Studio 2010 SDK。

注意事項注意事項

如需有關 Visual Studio 的 SDK 的詳細資訊,請參閱擴充 Visual Studio 的概觀。若要了解如何下載 Visual Studio 的 SDK,請參閱Visual Studio 擴充性開發人員中心 MSDN 網站上。

建立 MEF 專案

若要建立 MEF 專案

  1. 建立編輯器類別器的專案。 為方案命名 HighlightWordTest。

  2. VSIX 資訊清單編輯器中開啟 source.extension.vsixmanifest 檔案。

  3. 請確定Content名包含 MEF 元件的內容類型,並Path設定為 HighlightWordTest.dll。

  4. 儲存並關閉 source.extension.vsixmanifest。

  5. 刪除現有的類別檔案。

定義 TextMarkerTag

反白顯示文字的第一個步驟是子類別化TextMarkerTag ,並定義其外觀。

若要定義 TextMarkerTag 和 MarkerFormatDefinition

  1. 將類別檔案,並命名為 HighlightWordTag。

  2. 匯入下列命名空間。

    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel.Composition
    Imports System.Linq
    Imports System.Threading
    Imports System.Windows.Media
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Classification
    Imports Microsoft.VisualStudio.Text.Editor
    Imports Microsoft.VisualStudio.Text.Operations
    Imports Microsoft.VisualStudio.Text.Tagging
    Imports Microsoft.VisualStudio.Utilities
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Linq;
    using System.Threading;
    using System.Windows.Media;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Classification;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Operations;
    using Microsoft.VisualStudio.Text.Tagging;
    using Microsoft.VisualStudio.Utilities;
    
  3. 建立繼承自類別TextMarkerTag ,並命名為 HighlightWordTag。

    Friend Class HighlightWordTag
        Inherits TextMarkerTag
    
    internal class HighlightWordTag : TextMarkerTag
    
  4. 建立第二個類別繼承自MarkerFormatDefinition,並將它命名為 HighlightWordFormatDefinition。 若要使用此格式定義的索引標籤,您必須將它匯出具有下列屬性:

    <Export(GetType(EditorFormatDefinition))>
    <Name("MarkerFormatDefinition/HighlightWordFormatDefinition")>
    <UserVisible(True)>
    Friend Class HighlightWordFormatDefinition
        Inherits MarkerFormatDefinition
    
    [Export(typeof(EditorFormatDefinition))]
    [Name("MarkerFormatDefinition/HighlightWordFormatDefinition")]
    [UserVisible(true)]
    internal class HighlightWordFormatDefinition : MarkerFormatDefinition
    
  5. 在 HighlightWordFormatDefinition 的建構函式,定義其顯示名稱和外觀。 背景屬性定義的填滿色彩,而前景屬性定義的框線色彩。

    Public Sub New()
        Me.BackgroundColor = Colors.LightBlue
        Me.ForegroundColor = Colors.DarkBlue
        Me.DisplayName = "Highlight Word" 
        Me.ZOrder = 5
    End Sub
    
    public HighlightWordFormatDefinition()
    {
        this.BackgroundColor = Colors.LightBlue;
        this.ForegroundColor = Colors.DarkBlue;
        this.DisplayName = "Highlight Word";
        this.ZOrder = 5;
    }
    
  6. HighlightWordTag 的建構函式,傳遞剛剛建立的格式定義的名稱。

    Public Sub New()
        MyBase.New("MarkerFormatDefinition/HighlightWordFormatDefinition")
    End Sub
    
    public HighlightWordTag() : base("MarkerFormatDefinition/HighlightWordFormatDefinition") { }
    

實作 ITagger

下一步是實作ITagger介面。 這個介面會指派,以指定的文字緩衝區、 標記,它提供醒目秘訣的文字和其他視覺效果。

若要實作 tagger

  1. 建立一個類別,實作ITagger型別的HighlightWordTag,並命名為 HighlightWordTagger。

    Friend Class HighlightWordTagger
        Implements ITagger(Of HighlightWordTag)
    
    internal class HighlightWordTagger : ITagger<HighlightWordTag>
    
  2. 您可以將下列私用欄位和屬性加入類別:

    Private _View As ITextView
    Private Property View() As ITextView
        Get 
            Return _View
        End Get 
        Set(ByVal value As ITextView)
            _View = value
        End Set 
    End Property 
    Private _SourceBuffer As ITextBuffer
    Private Property SourceBuffer() As ITextBuffer
        Get 
            Return _SourceBuffer
        End Get 
        Set(ByVal value As ITextBuffer)
            _SourceBuffer = value
        End Set 
    End Property 
    Private _TextSearchService As ITextSearchService
    Private Property TextSearchService() As ITextSearchService
        Get 
            Return _TextSearchService
        End Get 
        Set(ByVal value As ITextSearchService)
            _TextSearchService = value
        End Set 
    End Property 
    Private _TextStructureNavigator As ITextStructureNavigator
    Private Property TextStructureNavigator() As ITextStructureNavigator
        Get 
            Return _TextStructureNavigator
        End Get 
        Set(ByVal value As ITextStructureNavigator)
            _TextStructureNavigator = value
        End Set 
    End Property 
    Private _WordSpans As NormalizedSnapshotSpanCollection
    Private Property WordSpans() As NormalizedSnapshotSpanCollection
        Get 
            Return _WordSpans
        End Get 
        Set(ByVal value As NormalizedSnapshotSpanCollection)
            _WordSpans = value
        End Set 
    End Property 
    Private _CurrentWord As System.Nullable(Of SnapshotSpan)
    Private Property CurrentWord() As System.Nullable(Of SnapshotSpan)
        Get 
            Return _CurrentWord
        End Get 
        Set(ByVal value As System.Nullable(Of SnapshotSpan))
            _CurrentWord = value
        End Set 
    End Property 
    Private _RequestedPoint As SnapshotPoint
    Private Property RequestedPoint() As SnapshotPoint
        Get 
            Return _RequestedPoint
        End Get 
        Set(ByVal value As SnapshotPoint)
            _RequestedPoint = value
        End Set 
    End Property 
    Private updateLock As New Object()
    
    ITextView View { get; set; }
    ITextBuffer SourceBuffer { get; set; }
    ITextSearchService TextSearchService { get; set; }
    ITextStructureNavigator TextStructureNavigator { get; set; }
    NormalizedSnapshotSpanCollection WordSpans { get; set; }
    SnapshotSpan? CurrentWord { get; set; }
    SnapshotPoint RequestedPoint { get; set; }
    object updateLock = new object();
    
  3. 新增的建構函式會初始化稍早所列的屬性,並將LayoutChangedPositionChanged事件處理常式。

    Public Sub New(ByVal view As ITextView, ByVal sourceBuffer As ITextBuffer, ByVal textSearchService As ITextSearchService, ByVal textStructureNavigator As ITextStructureNavigator)
        Me.View = view
        Me.SourceBuffer = sourceBuffer
        Me.TextSearchService = textSearchService
        Me.TextStructureNavigator = textStructureNavigator
        Me.WordSpans = New NormalizedSnapshotSpanCollection()
        Me.CurrentWord = Nothing 
        AddHandler Me.View.Caret.PositionChanged, AddressOf CaretPositionChanged
        AddHandler Me.View.LayoutChanged, AddressOf ViewLayoutChanged
    End Sub
    
    public HighlightWordTagger(ITextView view, ITextBuffer sourceBuffer, ITextSearchService textSearchService,
    ITextStructureNavigator textStructureNavigator)
    {
        this.View = view;
        this.SourceBuffer = sourceBuffer;
        this.TextSearchService = textSearchService;
        this.TextStructureNavigator = textStructureNavigator;
        this.WordSpans = new NormalizedSnapshotSpanCollection();
        this.CurrentWord = null;
        this.View.Caret.PositionChanged += CaretPositionChanged;
        this.View.LayoutChanged += ViewLayoutChanged;
    }
    
  4. 這兩者所呼叫的事件處理常式UpdateAtCaretPosition方法。

    Private Sub ViewLayoutChanged(ByVal sender As Object, ByVal e As TextViewLayoutChangedEventArgs)
        ' If a new snapshot wasn't generated, then skip this layout 
        If e.NewSnapshot IsNot e.OldSnapshot Then
            UpdateAtCaretPosition(View.Caret.Position)
        End If 
    End Sub 
    
    Private Sub CaretPositionChanged(ByVal sender As Object, ByVal e As CaretPositionChangedEventArgs)
        UpdateAtCaretPosition(e.NewPosition)
    End Sub
    
    void ViewLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
    {
        // If a new snapshot wasn't generated, then skip this layout 
        if (e.NewSnapshot != e.OldSnapshot)
        {
            UpdateAtCaretPosition(View.Caret.Position);
        }
    }
    
    void CaretPositionChanged(object sender, CaretPositionChangedEventArgs e)
    {
        UpdateAtCaretPosition(e.NewPosition);
    }
    
  5. 您也必須將TagsChanged事件,都會呼叫 update 方法。

    Public Event TagsChanged(ByVal sender As Object, ByVal e As SnapshotSpanEventArgs) _
        Implements ITagger(Of HighlightWordTag).TagsChanged
    
    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  6. UpdateAtCaretPosition()方法會尋找相同的文字游標所在位置,並會建構一份文字緩衝區中每個字SnapshotSpan可對應到這個字的項目。 接著,它呼叫SynchronousUpdate,哪一個引發TagsChanged事件。

    Private Sub UpdateAtCaretPosition(ByVal caretPosition As CaretPosition)
        Dim point As System.Nullable(Of SnapshotPoint) = caretPosition.Point.GetPoint(SourceBuffer, caretPosition.Affinity)
    
        If Not point.HasValue Then 
            Exit Sub 
        End If 
    
        ' If the new caret position is still within the current word (and on the same snapshot), we don't need to check it 
        If CurrentWord.HasValue AndAlso CurrentWord.Value.Snapshot Is View.TextSnapshot AndAlso point.Value > CurrentWord.Value.Start AndAlso point.Value < CurrentWord.Value.[End] Then 
            Exit Sub 
        End If
    
        RequestedPoint = point.Value
        UpdateWordAdornments()
    End Sub 
    
    Private Sub UpdateWordAdornments()
        Dim currentRequest As SnapshotPoint = RequestedPoint
        Dim wordSpans As New List(Of SnapshotSpan)()
        'Find all words in the buffer like the one the caret is on 
        Dim word As TextExtent = TextStructureNavigator.GetExtentOfWord(currentRequest)
        Dim foundWord As Boolean = True 
        'If we've selected something not worth highlighting, we might have missed a "word" by a little bit 
        If Not WordExtentIsValid(currentRequest, word) Then 
            'Before we retry, make sure it is worthwhile 
            If word.Span.Start <> currentRequest OrElse currentRequest = currentRequest.GetContainingLine().Start OrElse Char.IsWhiteSpace((currentRequest - 1).GetChar()) Then
                foundWord = False 
            Else 
                ' Try again, one character previous.  
                'If the caret is at the end of a word, pick up the word.
                word = TextStructureNavigator.GetExtentOfWord(currentRequest - 1)
    
                'If the word still isn't valid, we're done 
                If Not WordExtentIsValid(currentRequest, word) Then
                    foundWord = False 
                End If 
            End If 
        End If 
    
        If Not foundWord Then 
            'If we couldn't find a word, clear out the existing markers
            SynchronousUpdate(currentRequest, New NormalizedSnapshotSpanCollection(), Nothing)
            Exit Sub 
        End If 
    
        Dim currentWord__1 As SnapshotSpan = word.Span
        'If this is the current word, and the caret moved within a word, we're done. 
        If CurrentWord.HasValue AndAlso currentWord__1 = CurrentWord Then 
            Exit Sub 
        End If 
    
        'Find the new spans 
        Dim findData As New FindData(currentWord__1.GetText(), currentWord__1.Snapshot)
        findData.FindOptions = FindOptions.WholeWord Or FindOptions.MatchCase
    
        wordSpans.AddRange(TextSearchService.FindAll(findData))
    
        'If another change hasn't happened, do a real update 
        If currentRequest = RequestedPoint Then
            SynchronousUpdate(currentRequest, New NormalizedSnapshotSpanCollection(wordSpans), currentWord__1)
        End If 
    End Sub 
    Private Shared Function WordExtentIsValid(ByVal currentRequest As SnapshotPoint, ByVal word As TextExtent) As Boolean 
        Return word.IsSignificant AndAlso currentRequest.Snapshot.GetText(word.Span).Any(Function(c) Char.IsLetter(c))
    End Function
    
    void UpdateAtCaretPosition(CaretPosition caretPosition)
    {
        SnapshotPoint? point = caretPosition.Point.GetPoint(SourceBuffer, caretPosition.Affinity);
    
        if (!point.HasValue)
            return;
    
        // If the new caret position is still within the current word (and on the same snapshot), we don't need to check it 
        if (CurrentWord.HasValue
            && CurrentWord.Value.Snapshot == View.TextSnapshot
            && point.Value >= CurrentWord.Value.Start
            && point.Value <= CurrentWord.Value.End)
        {
            return;
        }
    
        RequestedPoint = point.Value;
        UpdateWordAdornments();
    }
    
    void UpdateWordAdornments()
    {
        SnapshotPoint currentRequest = RequestedPoint;
        List<SnapshotSpan> wordSpans = new List<SnapshotSpan>();
        //Find all words in the buffer like the one the caret is on
        TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest);
        bool foundWord = true;
        //If we've selected something not worth highlighting, we might have missed a "word" by a little bit
        if (!WordExtentIsValid(currentRequest, word))
        {
            //Before we retry, make sure it is worthwhile 
            if (word.Span.Start != currentRequest
                 || currentRequest == currentRequest.GetContainingLine().Start
                 || char.IsWhiteSpace((currentRequest - 1).GetChar()))
            {
                foundWord = false;
            }
            else
            {
                // Try again, one character previous.  
                //If the caret is at the end of a word, pick up the word.
                word = TextStructureNavigator.GetExtentOfWord(currentRequest - 1);
    
                //If the word still isn't valid, we're done 
                if (!WordExtentIsValid(currentRequest, word))
                    foundWord = false;
            }
        }
    
        if (!foundWord)
        {
            //If we couldn't find a word, clear out the existing markers
            SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null);
            return;
        }
    
        SnapshotSpan currentWord = word.Span;
        //If this is the current word, and the caret moved within a word, we're done. 
        if (CurrentWord.HasValue && currentWord == CurrentWord)
            return;
    
        //Find the new spans
        FindData findData = new FindData(currentWord.GetText(), currentWord.Snapshot);
        findData.FindOptions = FindOptions.WholeWord | FindOptions.MatchCase;
    
        wordSpans.AddRange(TextSearchService.FindAll(findData));
    
        //If another change hasn't happened, do a real update 
        if (currentRequest == RequestedPoint)
            SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), currentWord);
    }
    static bool WordExtentIsValid(SnapshotPoint currentRequest, TextExtent word)
    {
        return word.IsSignificant
            && currentRequest.Snapshot.GetText(word.Span).Any(c => char.IsLetter(c));
    }
    
  7. SynchronousUpdate上執行同步更新WordSpansCurrentWord屬性,並引發TagsChanged事件。

    Private Sub SynchronousUpdate(ByVal currentRequest As SnapshotPoint, ByVal newSpans As NormalizedSnapshotSpanCollection, ByVal newCurrentWord As System.Nullable(Of SnapshotSpan))
        SyncLock updateLock
            If currentRequest <> RequestedPoint Then 
                Exit Sub 
            End If
    
            WordSpans = newSpans
            CurrentWord = newCurrentWord
    
            RaiseEvent TagsChanged(Me, New SnapshotSpanEventArgs(New SnapshotSpan(SourceBuffer.CurrentSnapshot, 0, SourceBuffer.CurrentSnapshot.Length)))
        End SyncLock 
    End Sub
    
    void SynchronousUpdate(SnapshotPoint currentRequest, NormalizedSnapshotSpanCollection newSpans, SnapshotSpan? newCurrentWord)
    {
        lock (updateLock)
        {
            if (currentRequest != RequestedPoint)
                return;
    
            WordSpans = newSpans;
            CurrentWord = newCurrentWord;
    
            var tempEvent = TagsChanged;
            if (tempEvent != null)
                tempEvent(this, new SnapshotSpanEventArgs(new SnapshotSpan(SourceBuffer.CurrentSnapshot, 0, SourceBuffer.CurrentSnapshot.Length)));
        }
    }
    
  8. 您必須實作GetTags方法。 這個方法會使用一堆SnapshotSpan物件,並傳回標記 span 的列舉型別。

    在 C# 中,這個方法實作為利潤的 iterator,它可讓延遲評估 (也就是集中存取個別的項目時,才評估) 的標籤。 在 Visual Basic 中將標記新增至清單,並傳回清單。

    此方法會傳回TagSpan物件具有 「 藍色 」 TextMarkerTag,提供您一個藍色的背景。

    Public Function GetTags(ByVal spans As NormalizedSnapshotSpanCollection) As IEnumerable(Of ITagSpan(Of HighlightWordTag)) Implements ITagger(Of HighlightWordTag).GetTags
        If CurrentWord Is Nothing Then 
            Return Nothing 
            Exit Function 
        End If 
    
        ' Hold on to a "snapshot" of the word spans and current word, so that we maintain the same 
        ' collection throughout 
        Dim currentWord__1 As SnapshotSpan = CurrentWord.Value
        Dim wordSpans__2 As NormalizedSnapshotSpanCollection = WordSpans
    
        If spans.Count = 0 OrElse WordSpans.Count = 0 Then 
            Return Nothing 
            Exit Function 
        End If 
    
        ' If the requested snapshot isn't the same as the one our words are on, translate our spans to the expected snapshot 
        If spans(0).Snapshot IsNot wordSpans__2(0).Snapshot Then
            wordSpans__2 = New NormalizedSnapshotSpanCollection(wordSpans__2.[Select](Function(span) span.TranslateTo(spans(0).Snapshot, SpanTrackingMode.EdgeExclusive)))
    
            currentWord__1 = currentWord__1.TranslateTo(spans(0).Snapshot, SpanTrackingMode.EdgeExclusive)
        End If 
        'in order to emulate the C# yield return functionality, 
        'create a list and add all the relevant spans to it, then return the list 
        Dim list As List(Of TagSpan(Of HighlightWordTag))
        list = New List(Of TagSpan(Of HighlightWordTag))()
    
        If spans.OverlapsWith(New NormalizedSnapshotSpanCollection(currentWord__1)) Then
            list.Add(New TagSpan(Of HighlightWordTag)(CurrentWord, New HighlightWordTag()))
        End If 
    
        For Each span As SnapshotSpan In NormalizedSnapshotSpanCollection.Overlap(spans, wordSpans__2)
            list.Add(New TagSpan(Of HighlightWordTag)(span, New HighlightWordTag()))
        Next 
        Return List
    End Function
    
    public IEnumerable<ITagSpan<HighlightWordTag>> GetTags(NormalizedSnapshotSpanCollection spans)
    {
        if (CurrentWord == null)
            yield break;
    
        // Hold on to a "snapshot" of the word spans and current word, so that we maintain the same
        // collection throughout
        SnapshotSpan currentWord = CurrentWord.Value;
        NormalizedSnapshotSpanCollection wordSpans = WordSpans;
    
        if (spans.Count == 0 || wordSpans.Count == 0)
            yield break;
    
        // If the requested snapshot isn't the same as the one our words are on, translate our spans to the expected snapshot 
        if (spans[0].Snapshot != wordSpans[0].Snapshot)
        {
            wordSpans = new NormalizedSnapshotSpanCollection(
                wordSpans.Select(span => span.TranslateTo(spans[0].Snapshot, SpanTrackingMode.EdgeExclusive)));
    
            currentWord = currentWord.TranslateTo(spans[0].Snapshot, SpanTrackingMode.EdgeExclusive);
        }
    
        // First, yield back the word the cursor is under (if it overlaps) 
        // Note that we'll yield back the same word again in the wordspans collection; 
        // the duplication here is expected. 
        if (spans.OverlapsWith(new NormalizedSnapshotSpanCollection(currentWord)))
            yield return new TagSpan<HighlightWordTag>(currentWord, new HighlightWordTag());
    
        // Second, yield all the other words in the file 
        foreach (SnapshotSpan span in NormalizedSnapshotSpanCollection.Overlap(spans, wordSpans))
        {
            yield return new TagSpan<HighlightWordTag>(span, new HighlightWordTag());
        }
    }
    

建立 Tagger 提供者

若要建立您的 tagger,您必須實作IViewTaggerProvider。 您必須設定正確的屬性,以便在識別這個延伸,因此,這個類別會是 MEF 元件的組件。

注意事項注意事項

如需 MEF 的詳細資訊,請參閱 Managed Extensibility Framework (MEF)

若要建立 tagger 提供者

  1. 建立一個名為HighlightWordTaggerProvider實作IViewTaggerProvider,並將其與匯出ContentTypeAttribute的 「 文字 」,並TagTypeAttributeTextMarkerTag

    <Export(GetType(IViewTaggerProvider))>
    <ContentType("text")>
    <TagType(GetType(TextMarkerTag))>
    Friend Class HighlightWordTaggerProvider
        Implements IViewTaggerProvider
    
    [Export(typeof(IViewTaggerProvider))]
    [ContentType("text")]
    [TagType(typeof(TextMarkerTag))]
    internal class HighlightWordTaggerProvider : IViewTaggerProvider
    
  2. 您必須匯入兩個編輯器服務, ITextSearchServiceITextStructureNavigatorSelectorService、 tagger 具現化。

    Private _TextSearchService As ITextSearchService
    <Import()> _
    Friend Property TextSearchService() As ITextSearchService
        Get 
            Return _TextSearchService
        End Get 
        Set(ByVal value As ITextSearchService)
            _TextSearchService = value
        End Set 
    End Property 
    
    Private _TextStructureNavigatorSelector As ITextStructureNavigatorSelectorService
    <Import()>
    Friend Property TextStructureNavigatorSelector() As ITextStructureNavigatorSelectorService
        Get 
            Return _TextStructureNavigatorSelector
        End Get 
        Set(ByVal value As ITextStructureNavigatorSelectorService)
            _TextStructureNavigatorSelector = value
        End Set 
    End Property
    
    [Import]
    internal ITextSearchService TextSearchService { get; set; }
    
    [Import]
    internal ITextStructureNavigatorSelectorService TextStructureNavigatorSelector { get; set; }
    
  3. 實作CreateTagger``1方法,傳回的執行個體HighlightWordTagger

    Public Function CreateTagger(Of T As ITag)(ByVal textView As ITextView, ByVal buffer As ITextBuffer) As ITagger(Of T) Implements IViewTaggerProvider.CreateTagger
        'provide highlighting only on the top buffer 
        If textView.TextBuffer IsNot buffer Then 
            Return Nothing 
        End If 
    
        Dim textStructureNavigator As ITextStructureNavigator = TextStructureNavigatorSelector.GetTextStructureNavigator(buffer)
    
        Return TryCast(New HighlightWordTagger(textView, buffer, TextSearchService, textStructureNavigator), ITagger(Of T))
    End Function
    
    public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
    {
        //provide highlighting only on the top buffer 
        if (textView.TextBuffer != buffer)
            return null;
    
        ITextStructureNavigator textStructureNavigator =
            TextStructureNavigatorSelector.GetTextStructureNavigator(buffer);
    
        return new HighlightWordTagger(textView, buffer, TextSearchService, textStructureNavigator) as ITagger<T>;
    }
    

建置和測試程式碼

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

若要建置和測試 HighlightWordTest 的解決方案

  1. 建置方案。

  2. 當您執行此專案在偵錯工具時,會執行個體化 Visual Studio 的第二個執行個體。

  3. 建立一個文字檔,並輸入一些文字的文字會重複出現,比方說,"hello hello hello"。

  4. 將游標放置於其中一個"hello"的項目。 每次出現應該會以藍色來醒目提示。

請參閱

工作

逐步解說: 連結至檔案的副檔名的內容類型