WPF 实现 RichTextBox 关键字查询高亮

  • 一、环境说明
  • 二、代码
  • 三、演示结果
  • 四、参考资料

导言:我想实现一个简单的载入RTF文件到RichTextBox 中并可以查找关键字,并高亮关键字,提供上一个关键字与下一个关键字之间相互切换的效果,目前还有些小问题,就是RichTextBox 窗口导航到关键字的位置有些问题。

  • 建议先看 演示结果 再看看是不是你需要的

一、环境说明

  • 系统:Windows 10.0.19044 家庭版
  • 工具:Visual Stdio 2019 community
  • .Net:.Net FrameWork 4.6.2
  • 类型:WPF桌面应用

二、代码

1、前端代码

<Window x:Class="xx_MSS.Pages.IntroductionWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:xx_MSS.Pages"mc:Ignorable="d"  FontSize="18"Title="测试测试" Height="680" Width="1028"><Grid><Grid.RowDefinitions><RowDefinition Height="60"/><RowDefinition/></Grid.RowDefinitions><Grid Grid.Row="0"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/><ColumnDefinition Width="40"/></Grid.ColumnDefinitions><StackPanel Orientation="Horizontal" Grid.Column="0"><Label Content="质谱仪:" FontWeight="Bold" VerticalAlignment="Top" Margin="40, 10, 0,0" /><ComboBox Grid.Row="2" x:Name="m_combox" Width="150" Height="30" VerticalAlignment="Top" Margin="0, 10" SelectionChanged="upDateDoucument"><ComboBoxItem Content="质谱仪器1" IsSelected="True"/><ComboBoxItem Content="质谱仪器2"/></ComboBox></StackPanel><StackPanel Orientation="Horizontal"  Grid.Column="1"><Label Content="搜索:"  FontWeight="Bold"  VerticalAlignment="Top" Margin="10, 10, 0,0" /><TextBox x:Name="m_SearchTextBox" Width="300" Height="30" VerticalAlignment="Top"  Margin="0, 10" KeyUp="excetueSearch"/><Button x:Name="m_SearchBefore" Click="searchAfterBeforeBtnClicked" Height="30"  Content="《"  Width="40" Margin="0,10,0,20"/><Button x:Name="m_SearchAfter" Click="searchAfterBeforeBtnClicked" Height="30"  Margin="0,10,0,20" Content="》"  Width="40"/></StackPanel></Grid><RichTextBox x:Name="m_richText" Grid.Row="1" BorderThickness="0" Margin="60, 10, 60, 5" /></Grid>
</Window>

2、后端代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Diagnostics;namespace xx_MSS.Pages
{public class CommonColorsHelp{public static Color KeyFontColor = Color.FromRgb(0, 0, 0);public static Color DefaultFontColor = Color.FromRgb(0, 0, 0);public static Color SelectedKeyBackGroundColor = Color.FromRgb(234, 167, 255);public static Color SelectedKeyFontColor = Color.FromRgb(0, 0, 0);public static Color DefaultBackGroundColor = Color.FromRgb(255, 255, 255);}/// <summary>/// Introduction.xaml 的交互逻辑/// </summary>public partial class IntroductionWindow : Window{private Dictionary<string, string> m_mapBooksPairs;public IntroductionWindow(){InitializeComponent();m_richText.IsReadOnly = true;//绑定页面而已,在根路径下放置几个rtf文件即可m_mapBooksPairs = new Dictionary<string, string>();m_mapBooksPairs.Add("质谱仪器1", "./Documents/one.rtf");m_mapBooksPairs.Add("质谱仪器2", "./Documents/two.rtf");loadFile(m_combox.Text, m_richText);}/// <summary>///     加载文件/// </summary>/// <param name="filename"></param>/// <param name="richTextBox"></param>private  void loadFile(string filename, RichTextBox richTextBox){filename = m_mapBooksPairs[filename];if (string.IsNullOrEmpty(filename)){throw new ArgumentNullException();}if (!File.Exists(filename)){throw new FileNotFoundException();}using (FileStream stream = File.OpenRead(filename)){TextRange documentTextRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);string dataFormat = DataFormats.Text;string ext = System.IO.Path.GetExtension(filename);if (String.Compare(ext, ".xaml", true) == 0){dataFormat = DataFormats.Xaml;}else if (String.Compare(ext, ".rtf", true) == 0){dataFormat = DataFormats.Rtf;}documentTextRange.Load(stream, dataFormat);}}private void upDateDoucument(object sender, SelectionChangedEventArgs e){ComboBox comboBox = (ComboBox)sender;var name = comboBox.SelectedItem.ToString().Split(':')[1].Trim();if(m_mapBooksPairs != null){loadFile(name, m_richText);}}private void excetueSearch(object sender, KeyEventArgs e){if(e.Key == Key.Enter){               string searchKey = m_SearchTextBox.Text.Trim();if (searchKey != ""){ChangeSeachKeyWordsColor(searchKey);}else{ReSetBackGroundAll();}}}/// <summary>/// 改变在文章中用户搜索的关键字的字体颜色/// </summary>/// <param name="keyword"></param>public void ChangeSeachKeyWordsColor(string keyword){ChangeColorWithResout(keyword);}/// <summary>/// 改变关键字的字体颜色/// </summary>/// <param name="keyword">用户搜索关键字</param>/// <returns></returns>private List<TextRange> ChangeColorWithResout(string keyword){if (!string.IsNullOrEmpty(m_ProSearchkey)){ChangeColor(CommonColorsHelp.DefaultFontColor, m_ProSearchkey);ReSetBackGroundAll();}m_ProSearchkey = keyword;return ChangeColor(CommonColorsHelp.KeyFontColor, keyword);}/// <summary>/// 设置背景色/// </summary>/// <param name="l"></param>/// <param name="textRange"></param>public void SetBackGround(Color l, TextRange textRange){textRange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(l));textRange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(CommonColorsHelp.SelectedKeyFontColor));}/// <summary>/// 重新设置背景色/// </summary>/// <param name="textRange">关键字的的TextRange</param>/// <param name="isCurrKeyWord">是否是当前的关键字</param>public void ReSetBackGround(TextRange textRange, bool isCurrKeyWord){textRange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(CommonColorsHelp.DefaultBackGroundColor));if (isCurrKeyWord){textRange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(CommonColorsHelp.KeyFontColor));}else{textRange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(CommonColorsHelp.DefaultFontColor));}}/// <summary>/// 上一处/// </summary>public void SetUpBackGround(){if (m_TextList != null && m_TextList.Count > 0){//Rect r = m_TextList[currNumber].Start.GetCharacterRect(LogicalDirection.Backward);//m_richText.ScrollToVerticalOffset(r.Y);//FrameworkContentElement e = m_TextList[currNumber].Start.Parent as FrameworkContentElement;//if (e != null)//    e.BringIntoView();///滚动到指定位置var characterRect = m_TextList[currNumber].Start.GetCharacterRect(LogicalDirection.Forward);m_richText.ScrollToVerticalOffset(m_richText.VerticalOffset + characterRect.Top - m_richText.ActualHeight / 2d);ReSetBackGround(m_TextList[currNumber], true);currNumber--;if (currNumber < 0){currNumber = m_TextList.Count - 1;}SetBackGround(CommonColorsHelp.SelectedKeyBackGroundColor, m_TextList[currNumber]);}}/// <summary>/// 下一处/// </summary>public void SetDownBackGround(){if (m_TextList != null && m_TextList.Count > 0){//Rect r = m_TextList[currNumber].Start.GetCharacterRect(LogicalDirection.Backward);//m_richText.ScrollToVerticalOffset(r.Y);//FrameworkContentElement e = m_TextList[currNumber].Start.Parent as FrameworkContentElement;//if (e != null)//    e.BringIntoView();var characterRect = m_TextList[currNumber].Start.GetCharacterRect(LogicalDirection.Forward);m_richText.ScrollToVerticalOffset(m_richText.VerticalOffset + characterRect.Top - m_richText.ActualHeight / 2d);ReSetBackGround(m_TextList[currNumber], true);currNumber++;if (currNumber >= m_TextList.Count){currNumber = 0;}SetBackGround(CommonColorsHelp.SelectedKeyBackGroundColor, m_TextList[currNumber]);}}/// <summary>/// 改变关键字的具体实现/// </summary>/// <param name="l"></param>/// <param name="richTextBox1"></param>/// <param name="selectLength"></param>/// <param name="tpStart"></param>/// <param name="tpEnd"></param>/// <returns></returns>private TextPointer selecta(Color l, RichTextBox richTextBox1, int selectLength, TextPointer tpStart, TextPointer tpEnd){TextRange range = richTextBox1.Selection;range.Select(tpStart, tpEnd);//高亮选择range.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(l));return tpEnd.GetNextContextPosition(LogicalDirection.Forward);}/// <summary>/// 把所有背景恢复到默认/// </summary>private void ReSetBackGroundAll(){if (m_TextList != null){foreach (TextRange textRange in m_TextList){ReSetBackGround(textRange, false);}}}/// <summary>/// 当前第几处关键字被选中/// </summary>private int currNumber = 0;/// <summary>/// 改变关键字字体颜色/// </summary>/// <param name="l">颜色</param>/// <param name="keyword">关键字</param>/// <returns></returns>private List<TextRange> ChangeColor(Color l, string keyword){m_TextList = new List<TextRange>();//设置文字指针为Document初始位置           //richBox.Document.FlowDirection           TextPointer position = m_richText.Document.ContentStart;while (position != null){//向前搜索,需要内容为Text       if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text){//拿出Run的Text        string text = position.GetTextInRun(LogicalDirection.Forward);//可能包含多个keyword,做遍历查找           int index = 0;index = text.IndexOf(keyword, 0);if (index != -1){TextPointer start = position.GetPositionAtOffset(index);TextPointer end = start.GetPositionAtOffset(keyword.Length);m_TextList.Add(new TextRange(start, end));position = selecta(l, m_richText, keyword.Length, start, end);}}//文字指针向前偏移   position = position.GetNextContextPosition(LogicalDirection.Forward);}if (m_TextList != null && m_TextList.Count > 0){//重置currNumber = 0;SetBackGround(CommonColorsHelp.SelectedKeyBackGroundColor, m_TextList[currNumber]);}return m_TextList;}/// <summary>/// 当前关键字共搜索出的结果集合/// </summary>private List<TextRange> m_TextList;private string m_ProSearchkey;private void searchAfterBeforeBtnClicked(object sender, RoutedEventArgs e){Button button = (Button)sender;switch(button.Name){case "m_SearchBefore":SetUpBackGround();break;case "m_SearchAfter":SetDownBackGround();break;}}}
}

三、演示结果

四、参考资料

WPF搜索关键字:https://www.cnblogs.com/shanranlei/p/3635317.html
RichTextBox滚动到关键字位置:https://stackoverflow.com/questions/6908983/wpf-richtextbox-scroll-to-textpointer

WPF 实现 RichTextBox 关键字查询高亮相关推荐

  1. linux vim 高亮查找,vim搜索高亮关键字怎么取消,vim查询高亮搜索显示如何清除取消...

    如果我们在在打开的文件中使用Vim搜索功能并开启搜索高亮显示后怎么取消当前高亮显示搜索关键字呢? vim搜索高亮关键字如何取消,vim清除查询高亮搜索显示的方法 下面站长为大家介绍vim搜索高亮关键字 ...

  2. Elasticsearch实现商品搜索(关键字查询 条件筛选 规格过滤 价格区间搜索 分页查询 排序查询 高亮查询)

    Elasticsearch实现商品搜索 商品搜索 1.根据关键字查询 2.条件筛选 2.1 品牌筛选 2.1.1 需求分析 2.1.2 代码实现 2.2 规格过滤 2.2.1 需求分析 2.2.2 代 ...

  3. openlayers 2 高亮显示元素以及通过属性查询高亮某一元素

    本文参考官网例子,略作修改,直接上代码: 1.实现hover和click高亮显示 var map, controls;OpenLayers.Feature.Vector.style['default' ...

  4. Java根据学号提取班级_学生成绩管理系统 1. 能够实现根据以下关键字查询:学生姓名 、学号、班级、课 联合开发网 - pudn.com...

    学生成绩管理系统 所属分类:Java编程 开发工具:Java 文件大小:1204KB 下载次数:0 上传日期:2020-12-06 16:50:53 上 传 者:sunyue111 说明:  1. 能 ...

  5. 【Vue案例二】实现对表单数据的添加、删除以及关键字查询操作

    本文我们通过一个小案例来巩固一下前面学到的内容,即实现对表单数据的添加,删除和关键字查询的操作,具体案例效果如下: <!DOCTYPE html> <html lang=" ...

  6. Linux关键字查询

    Linux关键字查询 grep -R "查询关键字" /目录/* posted on 2017-09-12 15:46 流易 阅读(...) 评论(...) 编辑 收藏 转载于:h ...

  7. 高德地图2----输入提示、关键字查询

    我们在使用地图的时候经常会用到搜索地址并定位到该地址,高德的POI搜索:AMap.Autocomplete根据输入关键字提示匹配信息,可将Poi类型和城市作为输入提示的限制条件.用户可以通过自定义回调 ...

  8. java实现关键字查询_SpringData关键字查询实现方法详解

    一.创建项目并导入Jap相关依赖 1.1 org.springframework.boot spring-boot-starter-data-jpa com.alibaba druid-spring- ...

  9. ES关键字查询-特殊符号

    项目中ES关键字查询遇到的坑,本来如果在创建关键字字段的时候就应该限制一些特殊符号的输入的,比如限制只能输入字母下划线和数字这种,不用允许输入特殊符号(@,$,*...),结果项目经理不让,说是限制了 ...

最新文章

  1. pinpoint的id的生成
  2. 自然语言处理的发展历程
  3. python 安装PIL包的方法以及简单介绍
  4. 《数据安全法》今日实施,中国信通院联合百度等企业发起“数据安全推进计划”
  5. php+java+框架整合_ThinkPhP+Apache+PHPstorm整合框架流程图解
  6. vc 控制台添加托盘显示_和硕县塑胶托盘塑料周转筐多少钱、延安塑料物流箱
  7. 46. 全排列/47. 全排列 II
  8. [Web 前端] 018 css 清除浮动的四种方法
  9. Pillow和OpenCV转numpy数组
  10. Ubuntu系统打不开windows磁盘文件
  11. 智慧环卫全流程设计方案
  12. 软件工程项目:电梯调度
  13. 查看表空间和解决表空间扩容ORA-01119:ORA-27040问题
  14. 如何解决IAR不能设置断点的问题
  15. python库下载超时_Python的请求库超时,但是得到了响应
  16. rem命令使用 matlab,matlab中的rem怎么用?
  17. CSS进阶(一)背景与边框
  18. Python年会抽奖程序
  19. 甲骨文华育兴业-青柠成长计划
  20. 分享我的电子藏书:数据库系列

热门文章

  1. 博客群发(1)--构思
  2. python画鞭炮_Python实践|憨憨炸鞭炮
  3. Ubuntu 释放nvidia显存
  4. 中国新生儿重症监护呼吸机行业市场供需与战略研究报告
  5. 你们要的金海霸气bgm,直接复制打开就ok,京胡版本
  6. 计算机英语中liabilities,中国会计科目中英文对照(含科目代码)
  7. 5月19日----疯狂猜成语-----第四周第一次站立会议 杨霏,袁雪,胡潇丹,郭林林,尹亚男,赵静娜...
  8. Java学习之道:空指针错误求解救????????????
  9. 将Word文档转换为PDF时出现“PDFmaker文件遗失,要在修复模式下运行安装程序吗?”的提示
  10. 两个水果店挨着怎么竞争,水果店如何竞争对手