0

i want to color the matched text of a file. first,i load the file text into FileItem.Content ,then use regex to get the matches,and next put the Content into a richtextbox and use the matches to set the caret position and color the text . and the code to fill richtextbox

    RtbCodes.Document.Blocks.Clear();

    RtbCodes.Document.Blocks.Add(new Paragraph(new Run(item.Content)));
    foreach (Match m in item.Matches)
    {
        TextPointer start1 = RtbCodes.Document.ContentStart.GetPositionAtOffset(m.Index, LogicalDirection.Forward);
        TextPointer end = RtbCodes.Document.ContentStart.GetPositionAtOffset(m.Index + m.Length, LogicalDirection.Backward);
        if (start1 != null && end != null)
        {
            RtbCodes.Selection.Select(start1, end);
            RtbCodes.Selection.ApplyPropertyValue(Run.BackgroundProperty, "red");
        }

    }

my problem is the caret selection is not correct at all. see the picture bellow. my regex expression is [\$#]{[.a-zA-Z\d]+} ,so it will get #{blacklist.model1} , but it not. enter image description here

so ,what's wrong with richtextbox ?

enter image description here

goldii
  • 242
  • 2
  • 18
  • The html, regex, and the `FileItem` class are not actually needed to reproduce the issue. But they can scare people away because they feel it is quite challenging to even repro the issue you are facing. If you provide a simple example - a RichTextBox, a Paragraph, a Run, that 's all needed to demo the issue - you can get an answer very quickly - usually in a few minutes. – kennyzx Jun 21 '18 at 04:20
  • thank for suggestion. – goldii Jun 21 '18 at 05:21

1 Answers1

1

You are counting in the invisible "ElementStart" symbols at the beginning of the document, that's why the offset of the selection is incorrect.

To get the correct position, you can count from the beginning of the Run element.

var newRun = new Run(item.Content);
RtbCodes.Document.Blocks.Add(new Paragraph(newRun));

TextPointer start1 = newRun.ContentStart.GetPositionAtOffset(m.Index, LogicalDirection.Forward);
TextPointer end = newRun.ContentStart.GetPositionAtOffset(m.Index + m.Length, LogicalDirection.Backward);
kennyzx
  • 12,845
  • 6
  • 39
  • 83
  • thanks for answer.but it still incorrect from the second match. see the second picture.[link](https://i.stack.imgur.com/H2UJX.png) – goldii Jun 21 '18 at 05:37
  • base on you code **newRun** , i made a change. ' var i = 0; foreach (Match m in item.Matches) { var x = 4 * i; TextPointer start1 = newRun.ContentStart.GetPositionAtOffset(m.Index + x, LogicalDirection.Forward); TextPointer end = newRun.ContentStart.GetPositionAtOffset(m.Index + m.Length + x, LogicalDirection.Backward); .... i++; }' then it works. but why 4* need ? – goldii Jun 21 '18 at 05:49
  • In the `foreach` loop, every time you highlight a selection, you are inserting more "invisible" symbols...so the offset keeps drifting away, you can figure out the solution: first find out all the selections in the `foreach` loop, save them to a collection, then high light them one by one (in another `foreach` loop). – kennyzx Jun 21 '18 at 05:51
  • yes ,you are right. it works find. thank you very much. – goldii Jun 21 '18 at 06:02