views:

192

answers:

1

Dear community.

I have now used way too long time, trying to figure out a problem, which I didn't think would be that hard.

Here is the deal:

I am writing a small application using C# and WPF.

I have a RichTextBox containing a FlowDocument.

I have added a small textbox and a button below my richtextbox.

The user then types in the word he/she wishes to search for, and presses the button.

The richtextbox will then jump to the first occurrance of that word.

it is enough that it just jumps to the correct line - it can also select, highlight or place the cursor by the word - anything will do, as long as the richTextBox is scrolled to the word.

Continuing to press the button, will then jump to the next occurance of the word, and so on so forth, till the end of the document.

As I said - I thought it to be a simple task - however I am having serious problems figuring this out.

I hope you will be able to help me.

All the best

/Sagi

A: 

This should do the job:

public bool DoSearch(RichTextBox richTextBox, string searchText, bool searchNext)
{
  TextRange searchRange;

  // Get the range to search
  if(searchNext)
    searchRange = new TextRange(
        richTextBox.Selection.Start.GetPositionAtOffset(1),
        richTextBox.Document.ContentEnd);
  else
    searchRange = new TextRange(
        richTextBox.Document.ContentStart,
        richTextBox.Document.ContentEnd);

  // Do the search
  TextRange foundRange = FindTextInRange(searchRange, searchText);
  if(foundRange==null)
    return false;

  // Select the found range
  richTextBox.Selection.Select(foundRange.Start, foundRange.End);
  return true; 
}

public TextRange FindTextInRange(TextRange searchRange, string searchText)
{
  // Search the text with IndexOf
  int offset = searchRange.Text.IndexOf(searchText);
  if(offset<0)
    return null;  // Not found

  // Try to select the text as a contiguous range
  for(TextPointer start = searchRange.Start.GetPositionAtOffset(offset); start != searchRange.End; start = start.GetPositionAtOffset(1))
  {
    TextRange result = new TextRange(start, start.GetPositionAtOffset(searchText.Length);
    if(result.Text == searchText)
      return result;
  }
  return null;
}

The reason for the for() loop in FindTextInRangeUnfortunately the range.Text strips out non-text characters, so in some cases the offset computed by IndexOf will be slightly too low.

Ray Burns
It worked like a charm.Thanks a million for your answer, buddy. You have no idea how much you helped me.Have a nice day!
Sagi1981
The first return in FindTextInRange should however he changed to a null, instead of a false :)
Sagi1981
Thanks. That's what happens when you type up an idea and don't bother to try it out. I edited false -> null it in my answer.
Ray Burns