title: Select Range of Text in WPF RichTextBox (FlowDocument) Programmatically
body: <p>I have this WPF RichTextBox and I want to programmatically select a given range of letters/words and highlight it. I've tried this, but it doesn't work, probably because I'm not taking into account some hidden FlowDocument tags or similar. For example, I want to select letters 3-8 but 2-6 gets selected):</p>
  
  <pre><code>var start = MyRichTextBox.Document.ContentStart;
  var startPos = start.GetPositionAtOffset(3);
  var endPos = start.GetPositionAtOffset(8);
  var textRange = new TextRange(startPos,endPos);
  textRange.ApplyPropertyValue(TextElement.ForegroundProperty,
      new SolidColorBrush(Colors.Blue));
  textRange.ApplyPropertyValue(TextElement.FontWeightProperty, 
      FontWeights.Bold);
  </code></pre>
  
  <p>I've realised RichTextBox handling is a bit trickier than I thought :)</p>
  
  <p>Update: I got a few answers on the MSDN forums: <a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/01c9faac-2c37-40ca-9ca5-91d433033671/" rel="noreferrer">This thread</a> where "dekurver" seid: </p>
  
  <blockquote>
    <p>The offsets you're specifying are not
    character offsets but symbol offsets.
    What you need to do is get a
    TextPointer that you know is adjacent
    to text, then you can add character
    offsets.</p>
  </blockquote>
  
  <p>And "LesterLobo" said:</p>
  
  <blockquote>
    <p>you will need to loop through the
    paragraphs and inlines to find the
    Next and then their offsets in a loop
    to apply for all appearances of the
    specific text. note that when you edit
    your text would move but your
    highlight wouldnt move as its
    associated with the offset not the
    text. You could however create a
    custom run and provide a highlight for
    it...</p>
  </blockquote>
  
  <p>Would still LOVE to see some sample code for this if someone knows their way around FlowDocuments...</p>
  
  <p><em>EDIT</em> I got a version of Kratz VB code working, it looks like this:</p>
  
  <pre><code>private static TextPointer GetPoint(TextPointer start, int x)
  {
      var ret = start;
      var i = 0;
      while (i &lt; x &amp;&amp; ret != null)
      {
          if (ret.GetPointerContext(LogicalDirection.Backward) == 
  TextPointerContext.Text ||
              ret.GetPointerContext(LogicalDirection.Backward) == 
  TextPointerContext.None)
              i++;
          if (ret.GetPositionAtOffset(1, 
  LogicalDirection.Forward) == null)
              return ret;
          ret = ret.GetPositionAtOffset(1, 
  LogicalDirection.Forward);
      }
      return ret;
  }
  </code></pre>
  
  <p>And I use it like this:</p>
  
  <pre><code>Colorize(item.Offset, item.Text.Length, Colors.Blue);
  
  private void Colorize(int offset, int length, Color color)
  {
      var textRange = MyRichTextBox.Selection;
      var start = MyRichTextBox.Document.ContentStart;
      var startPos = GetPoint(start, offset);
      var endPos = GetPoint(start, offset + length);
  
      textRange.Select(startPos, endPos);
      textRange.ApplyPropertyValue(TextElement.ForegroundProperty, 
  new SolidColorBrush(color));
      textRange.ApplyPropertyValue(TextElement.FontWeightProperty, 
  FontWeights.Bold);
  }
  </code></pre>