Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

making a simple search function, making the cursor jump to (or highlight) the word that is searched for

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.

like image 284
Sagi1981 Avatar asked Nov 18 '09 15:11

Sagi1981


1 Answers

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.

like image 175
Ray Burns Avatar answered Sep 17 '22 17:09

Ray Burns