Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Highlight parts of text in FlowDocument

I want to highlight some parts of text in a FlowDocument based on the search results. What I am doing is getting the indexes where the searched word occures in the text of the FlowDocument and then apply background color on the text range starting at the found index, ending at the found index + search word length.

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);

The problem is, that I am searching indexes in the text of the document but when I'm returning the FlowDocument the xaml tags are added and I see the highlights moved. How can I fix it?

like image 707
kzub Avatar asked Sep 12 '13 09:09

kzub


1 Answers

Finaly, inspired by the answer of user007, after making some modifications I managed to highlight all the occurences of a string in a FlowDocument. Here is my code:

for (TextPointer position = newDocument.ContentStart;
        position != null && position.CompareTo(newDocument.ContentEnd) <= 0;
        position = position.GetNextContextPosition(LogicalDirection.Forward))
{
    if (position.CompareTo(newDocument.ContentEnd) == 0)
    {
        return newDocument;
    }

    String textRun = position.GetTextInRun(LogicalDirection.Forward);
    StringComparison stringComparison = StringComparison.CurrentCulture;
    Int32 indexInRun = textRun.IndexOf(search, stringComparison);
    if (indexInRun >= 0)
    {
        position = position.GetPositionAtOffset(indexInRun);
        if (position != null)
        {
            TextPointer nextPointer = position.GetPositionAtOffset(search.Length);
            TextRange textRange = new TextRange(position, nextPointer);
            textRange.ApplyPropertyValue(TextElement.BackgroundProperty, 
                          new SolidColorBrush(Colors.Yellow));
        }
    }
}
like image 53
kzub Avatar answered Sep 21 '22 18:09

kzub