7

FlowDocument検索結果に基づいて、テキストの一部を強調表示したいと考えています。私がやっていることは、検索された単語がのテキストで発生するインデックスを取得FlowDocumentし、見つかったインデックスから始まり、見つかったインデックス + 検索語の長さで終わるテキスト範囲に背景色を適用することです。

TextRange content = new TextRange(myFlowDocument.ContentStart, 
                                  myFlowDocument.ContentEnd);
List<int> highlights = GetHighlights(content.Text, search);

foreach (int index in highlights)
{
    var start = myFlowDocument.ContentStart;
    var startPos = start.GetPositionAtOffset(index);
    var endPos = start.GetPositionAtOffset(index + search.Length);
    var textRange = new TextRange(startPos, endPos);
    textRange.ApplyPropertyValue(TextElement.BackgroundProperty, 
               new SolidColorBrush(Colors.Yellow));
}

TextRange newRange = new TextRange(myFlowDocument.ContentStart, 
                                   newDocument.ContentEnd);
FlowDocument fd = (FlowDocument)XamlReader.Parse(newRange.Text);

問題は、ドキュメントのテキストでインデックスを検索しているのですが、返すときにFlowDocumentxaml タグが追加され、ハイライトが移動していることです。どうすれば修正できますか?

4

3 に答える 3

0

kzubの答えは私にはうまくいかないようだったのでuser007、 TextPointer テキストの部分文字列のすべてのインスタンスを強調表示するために拡張するソリューションも作成しました。また、大文字と小文字を区別せず、すべての一致を強調表示します。

    public static void HighlightWords(TextPointer text, string searchWord, string stringText)
    {
        int instancesOfSearchKey = Regex.Matches(stringText.ToLower(), searchWord.ToLower()).Count;

        for (int i = 0; i < instancesOfSearchKey; i++)
        {
            int lastInstanceIndex = HighlightNextInstance(text, searchWord);
            if (lastInstanceIndex == -1)
            {
                break;
            }
            text = text.GetPositionAtOffset(lastInstanceIndex);
        }
    }

    private static int HighlightNextInstance(TextPointer text, string searchWord)
    {
        int indexOfLastInstance = -1;

        while (true)
        {
            TextPointer next = text.GetNextContextPosition(LogicalDirection.Forward);
            if (next == null)
            {
                break;
            }
            TextRange newText = new TextRange(text, next);

            int index = newText.Text.ToLower().IndexOf(searchWord.ToLower());
            if (index != -1)
            {
                indexOfLastInstance = index;
            }

            if (index > 0)
            {
                TextPointer start = text.GetPositionAtOffset(index);
                TextPointer end = text.GetPositionAtOffset(index + searchWord.Length);
                TextRange textRange = new TextRange(start, end);
                textRange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.Yellow));
            }
            text = next;
        }

        return indexOfLastInstance;
    }
于 2018-07-18T21:54:03.513 に答える