WPF RichEditBox文本查找、光标定位及滚动至视图技术求助
WPF RichTextBox 文本搜索定位与滚动示例
以下是可直接运行的WPF示例,实现可编辑RichTextBox的文本搜索、光标定位及自动滚动到视图功能:
XAML 布局
<Window x:Class="WpfRichTextSearch.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="RichTextBox 文本搜索" Height="450" Width="800"> <Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Margin="0 0 0 10"> <TextBox x:Name="txtSearch" Width="200" Margin="0 0 10 0" Watermark="输入搜索文本"/> <Button x:Name="btnSearch" Content="查找下一个" Click="BtnSearch_Click"/> </StackPanel> <RichTextBox x:Name="richTextBox" Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"> <FlowDocument> <Paragraph> WPF的RichTextBox是一个可编辑的富文本控件,相比DocumentViewer的只读模式,它支持用户修改内容。 我们需要实现文本搜索功能,找到目标文本后将光标定位到该处,并自动滚动到视图范围内。 比如这段文本中的"文本搜索"就是我们要查找的关键词,多次点击查找按钮可以循环定位所有匹配项。 </Paragraph> <Paragraph> 另外,还要处理搜索到末尾后从头开始的逻辑,以及没有找到匹配项时的提示。 </Paragraph> </FlowDocument> </RichTextBox> </Grid> </Window>
C# 后台逻辑
using System; using System.Windows; using System.Windows.Documents; namespace WpfRichTextSearch { public partial class MainWindow : Window { private TextPointer _searchStartPosition; public MainWindow() { InitializeComponent(); _searchStartPosition = richTextBox.Document.ContentStart; } private void BtnSearch_Click(object sender, RoutedEventArgs e) { string searchText = txtSearch.Text.Trim(); if (string.IsNullOrEmpty(searchText)) return; // 从当前起始位置查找 TextRange currentRange = new TextRange(_searchStartPosition, richTextBox.Document.ContentEnd); TextRange matchRange = FindTextInRange(currentRange, searchText); if (matchRange != null) { SelectAndScrollToMatch(matchRange); _searchStartPosition = matchRange.End; } else { // 当前范围无匹配,从头开始搜索 currentRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); matchRange = FindTextInRange(currentRange, searchText); if (matchRange != null) { SelectAndScrollToMatch(matchRange); _searchStartPosition = matchRange.End; } else { MessageBox.Show("未找到匹配文本"); _searchStartPosition = richTextBox.Document.ContentStart; } } } // 在指定文本范围内查找目标文本 private TextRange FindTextInRange(TextRange range, string searchText) { int matchIndex = range.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase); if (matchIndex < 0) return null; // 转换为TextPointer定位富文本位置 TextPointer start = range.Start.GetPositionAtOffset(matchIndex, LogicalDirection.Forward); TextPointer end = start.GetPositionAtOffset(searchText.Length, LogicalDirection.Forward); return new TextRange(start, end); } // 选中匹配文本并滚动到视图 private void SelectAndScrollToMatch(TextRange matchRange) { richTextBox.Selection.Select(matchRange.Start, matchRange.End); // 获取匹配文本的位置,计算滚动偏移使其居中显示 Rect matchRect = matchRange.Start.GetCharacterRect(LogicalDirection.Forward); richTextBox.ScrollToVerticalOffset(richTextBox.VerticalOffset + matchRect.Top - richTextBox.ActualHeight / 2); // 让RichTextBox获得焦点,确保光标可见 richTextBox.Focus(); } } }
关键说明
- 文本查找:通过
TextRange.Text提取纯文本进行匹配,再转换为TextPointer定位富文本位置,兼容带格式的内容。 - 光标定位:使用
Selection.Select选中匹配文本,自动将光标定位到目标区域。 - 滚动适配:通过
GetCharacterRect获取匹配文本的坐标,计算滚动偏移让目标内容尽量显示在控件中间。 - 循环搜索:当搜索到文档末尾时自动从头开始,支持连续查找所有匹配项。
- 大小写控制:如需区分大小写,将
StringComparison.OrdinalIgnoreCase替换为StringComparison.Ordinal即可。
内容的提问来源于stack exchange,提问作者TreeDragon
相关产品推荐
相关产品推荐

