Struggling to find a clear WPF (not Forms) example of finding cursor position of searched text and then scrolling text into view using a RichEditBox.
DocumentViewer has the desired text search ability but is read only and I require write.
Struggling to find a clear WPF (not Forms) example of finding cursor position of searched text and then scrolling text into view using a RichEditBox.
DocumentViewer has the desired text search ability but is read only and I require write.
On
// Function to search a string in a RichTextBox and scroll it into view
public void SearchAndScroll(RichTextBox richTextBox, string searchText)
{
// Get a TextRange for the entire document
TextRange textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
// Find the first match
TextRange searchRange = FindTextInRange(textRange, searchText);
if (searchRange != null)
{
// Select the searched text in the RichTextBox
richTextBox.Selection.Select(searchRange.Start, searchRange.End);
// Scroll the searched text into view
richTextBox.ScrollToVerticalOffset(richTextBox.VerticalOffset + richTextBox.Selection.Start.GetCharacterRect(LogicalDirection.Forward).Top);
richTextBox.Focus();
}
}
// Function to find a string in a TextRange
public TextRange FindTextInRange(TextRange searchRange, string searchText)
{
// The start position of the search
TextPointer current = searchRange.Start.GetInsertionPosition(LogicalDirection.Forward);
while (current != null)
{
// The TextRange that contains the current character
TextRange text = new TextRange(current.GetPositionAtOffset(0, LogicalDirection.Forward), current.GetPositionAtOffset(1, LogicalDirection.Forward));
// If the current character is the start of the searched text
if (text.Text == searchText[0].ToString())
{
TextRange match = new TextRange(current, current.GetPositionAtOffset(searchText.Length, LogicalDirection.Forward));
if (match.Text == searchText)
{
// Return the match
return match;
}
}
// Move to the next character
current = current.GetPositionAtOffset(1, LogicalDirection.Forward);
}
// Return null if no match found
return null;
}
Faster response
Answer derived from link...
RichTextBox uses a FlowDocument to represent images, formatting... in addition to text. The catch is TextRange.Text.IndexOf(string, start) returns the index within text, not the FlowDocument's TextPointer position!
To get the TextPointer requires indexing through FlowDocument. But this is very slow. By checking each FlowDocument Block for the searched for string and only indexing through this block significantly improves search time.
For StringComparison that include IgnoreCase ensure searched for string is lower case.
Find the TextRange by indexing through the searchRange known to contain the searched for text.
Html for RichTextBox