WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能

简介: 很多工程软件拥有自己定义的脚本语言,作为程序员用惯了具有高亮显示和智能提示功能的编辑器,所以针对特定的脚本自己开发一个编辑器。主要采用WPF、C#语言以及AvalonEdit控件。

WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能

很多工程软件拥有自己定义的脚本语言,作为程序员用惯了具有高亮显示和智能提示功能的编辑器,所以针对特定的脚本自己开发一个编辑器。主要采用WPF、C#语言以及AvalonEdit控件。

WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能AvlonEdit控件实现自定义高亮显示实现文本搜索实现文本替换自定义搜索栏用户控件实现自定义搜索实现自定义替换

AvlonEdit控件

AvalonEdit是基于WPF的代码显示控件,可以支持代码高亮显示、智能提示、代码折叠等功能。

image.png

AvalonEdit项目官网

在WPF中使用AvalonEdit非常简单,直接Nuget安装,然后引入命名空间xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit",最后直接使用即可<avalonEdit:TextEditor/>。因为本文后面要实现自定义替换,需要对源码进行修改及重新编译,所以最好直接下载源码。

实现自定义高亮显示

AvalonEdit已经内置了C#、C++、Java等常见语言的高亮显示,如果要为自定义的语言进行语法高亮需要写一个*.xshd文件,该文件的基本使用如下:

<?xmlversion="1.0"?>

<SyntaxDefinitionname="Custom Highlighting"xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">

 <!--设置颜色与文本风格,如粗体,背景色等-->

 <Colorname="Comment"foreground="#C6B1B1"exampleText="* comment"/>

 <Colorname="Card"fontWeight="bold"foreground="#960092"exampleText="=CSTR"/>

 <Colorname="Field"fontWeight="bold"foreground="#3A76D7"exampleText="CA"/>

   <!-- 主要的规则集 -->

   <RuleSet>

   <!--以//开头或者包裹在/*..*/中的文本使用Comment颜色-->

       <Spancolor="Comment"begin="//"/>

       <Spancolor="Comment"multiline="true"begin="/\*"end="\*/"/>

       

       <Spancolor="String">

           <Begin>"</Begin>

           <End>"</End>

     <!--可以定义规则子集-->

           <RuleSet>

               <Spanbegin="\\"end="."/>

           </RuleSet>

       </Span>

       <!--定义关键词-->

       <KeywordsfontWeight="bold"foreground="Blue">

           <Word>if</Word>

           <Word>else</Word>

           <!-- ... -->

       </Keywords>

       <!-- 可以使用正则进行定义 -->

       <Ruleforeground="DarkBlue">

           \b0[xX][0-9a-fA-F]+  # hex number

       |    \b

           (    \d+(\.[0-9]+)?   #number with optional floating point

           |    \.[0-9]+         #or just starting with floating point

           )

           ([eE][+-]?[0-9]+)? # optional exponent

       </Rule>

   </RuleSet>

</SyntaxDefinition>

自定义完*.xshd文件后,一定要设置文件的属性

设置完成后,需要在程序中设置加载

//注册自定义高亮

IHighlightingDefinitioncustomHighlighting;

using (Streams=typeof(MainWindow).Assembly.GetManifestResourceStream("NotConvertPeps.PEPSHighlighting.xshd"))

{

    using (XmlReaderreader=newXmlTextReader(s))

    {

        customHighlighting=HighlightingLoader.Load(reader, HighlightingManager.Instance);

    }

}

//要设置一个后缀名字,在这里我设置了fre

HighlightingManager.Instance.RegisterHighlighting("Custom Highlighting", newstring[] { ".fre" }, customHighlighting);

InitializeComponent();

//在InitializeComponent()之后使用,为txtEdit设置高亮语法

txtEditor.SyntaxHighlighting=HighlightingManager.Instance.GetDefinitionByExtension(".fre");

设置完成后,看下效果

实现文本搜索

AvalonEdit已经具有了搜索功能,新版本只需使用ICSharpCode.AvalonEdit.Search.SearchPanel.Install(txtEditor);便可以使用Ctrl+F调出搜索栏,该搜索栏具有是否忽略大小写、是否全字匹配、是否使用正则三个设置项,而且还有背景显示、下拉框自动下拉等功能,基本满足要求。

实现文本替换

很遗憾AvalonEdit没有提供像搜索栏一样的功能,必须自己来实现。

自定义搜索栏用户控件

仿照VS的替换栏进行页面设计

其中注册replaceContent、findContent、CareCase、MatchAll等依赖属性进行绑定,值得注意的是,用户控件在绑定的时候,source要用RelativeSource,否则不能实现数据更新,正确绑定方式如下:

<CheckBox

   x:Name="chxCareCase"

   IsChecked="{Binding CareCase,RelativeSource={RelativeSource AncestorType=local:ReplaceControl}}"

   Template="{StaticResource ToggleButtonControlTemplate2}"

   ToolTip="区分大小写"/>

实现自定义搜索

因为替换操作仍然需要先查询再替换,所以需要自定义实现搜索。实现思路可以是得到textEditor中的text,然后使用string.index等方法进行,但是这样太麻烦,而且还需要自定义搜索结果的背景高亮以及文本选择。所以要换个思路,因为AvalonEdit已经提供了搜索功能,所以一定会有相关的接口,与查询有关的代码都存在于ICSharpCode.AvalonEdit.Search命名空间下,主要的查询方法存在于ICSharpCode.AvalonEdit.Search.SearchPanel中,其中最关键的查询方法是SearchStrategyFactory.Create(SearchPattern, !MatchCase, WholeWords, UseRegex ? SearchMode.RegEx : SearchMode.Normal);

除了该方法外,我们还需要进行上一个和下一个搜索以及搜索结果的背景高亮显示,这都和SearchResultBackgroundRenderer类相关,但是AvalonEdit官方源码中,该类的访问权限是Private,所以需要将访问权限改为public,然后重新编译。

实现自定义搜索功能C#代码

SearchResultBackgroundRendererrenderer=newSearchResultBackgroundRenderer();

voidDoFind()

{

   renderer.CurrentResults.Clear();//清空已经搜索出的结果

   if (!string.IsNullOrEmpty(replaceUserControl.findContent))

   {

       //文字的背景高亮

       textArea.TextView.BackgroundRenderers.Clear();

       textArea.TextView.BackgroundRenderers.Add(renderer);

       //搜索的管件方法

       ISearchStrategystrategy=SearchStrategyFactory.Create(replaceUserControl.findContent, !replaceUserControl.CareCase, replaceUserControl.MatchAll, replaceUserControl.regex?SearchMode.RegEx : SearchMode.Normal);

       varresults=strategy.FindAll(textArea.Document, 0, textArea.Document.TextLength);

       //将搜索的结果全部加到renderer.CurrentResults中,方便后续的进行上一个、下一个搜索的展示

       foreach (SearchResultresultinresults)

       {

           renderer.CurrentResults.Add(result);

       }

   }

}

实现下一个

privatevoidFindNext(objectsender, RoutedEventArgse)

{

   DoFind();

   

   SearchResultresult=renderer.CurrentResults.FindFirstSegmentWithStartAfter(textArea.Caret.Offset+1);

   if (result==null)

       result=renderer.CurrentResults.FirstSegment;

   if (result!=null)

   {

       SelectResult(result);

   }

}

实现上一个

privatevoidFindPre(objectsender, RoutedEventArgse)

{

   DoFind();

   SearchResultresult=renderer.CurrentResults.FindFirstSegmentWithStartAfter(textArea.Caret.Offset);

   if (result!=null)

       result=renderer.CurrentResults.GetPreviousSegment(result);

   if (result==null)

       result=renderer.CurrentResults.LastSegment;

   if (result!=null)

   {

       SelectResult(result);

   }

}

实现效果

实现自定义替换

AvalonEdit提供了Document.Replace方法,可以直接使用

privatevoidReplaceNext(objectsender, RoutedEventArgse)

{

   stringreplace=replaceUserControl.replaceContent;

   DoFind();

   SearchResultresult=renderer.CurrentResults.FindFirstSegmentWithStartAfter(textArea.Caret.Offset+1);

   if (result==null)

       result=renderer.CurrentResults.FirstSegment;

   if (result!=null)

   {

       SelectResult(result);

       this.txtEditor.Document.Replace(result.StartOffset, result.Length, replace);

       DoFind();//必须调用一次,不然查询出的字段背景色会乱

   }

}

WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能AvlonEdit控件实现自定义高亮显示实现文本搜索实现文本替换自定义搜索栏用户控件实现自定义搜索实现自定义替换


相关文章
|
3月前
|
C# 机器学习/深度学习 搜索推荐
WPF与机器学习的完美邂逅:手把手教你打造一个具有智能推荐功能的现代桌面应用——从理论到实践的全方位指南,让你的应用瞬间变得高大上且智能无比
【8月更文挑战第31天】本文详细介绍如何在Windows Presentation Foundation(WPF)应用中集成机器学习功能,以开发具备智能化特性的桌面应用。通过使用Microsoft的ML.NET框架,本文演示了从安装NuGet包、准备数据集、训练推荐系统模型到最终将模型集成到WPF应用中的全过程。具体示例代码展示了如何基于用户行为数据训练模型,并实现实时推荐功能。这为WPF开发者提供了宝贵的实践指导。
43 0
|
3月前
|
开发者 C# UED
WPF与多媒体:解锁音频视频播放新姿势——从界面设计到代码实践,全方位教你如何在WPF应用中集成流畅的多媒体功能
【8月更文挑战第31天】本文以随笔形式介绍了如何在WPF应用中集成音频和视频播放功能。通过使用MediaElement控件,开发者能轻松创建多媒体应用程序。文章详细展示了从创建WPF项目到设计UI及实现媒体控制逻辑的过程,并提供了完整的示例代码。此外,还介绍了如何添加进度条等额外功能以增强用户体验。希望本文能为WPF开发者提供实用的技术指导与灵感。
142 0
|
3月前
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
60 0
|
3月前
|
API C# Shell
WPF与Windows Shell完美融合:深入解析文件系统操作技巧——从基本文件管理到高级Shell功能调用,全面掌握WPF中的文件处理艺术
【8月更文挑战第31天】Windows Presentation Foundation (WPF) 是 .NET Framework 的关键组件,用于构建 Windows 桌面应用程序。WPF 提供了丰富的功能来创建美观且功能强大的用户界面。本文通过问题解答的形式,探讨了如何在 WPF 应用中集成 Windows Shell 功能,并通过具体示例代码展示了文件系统的操作方法,包括列出目录下的所有文件、创建和删除文件、移动和复制文件以及打开文件夹或文件等。
76 0
|
3月前
|
C# Windows 监控
WPF应用跨界成长秘籍:深度揭秘如何与Windows服务完美交互,扩展功能无界限!
【8月更文挑战第31天】WPF(Windows Presentation Foundation)是 .NET 框架下的图形界面技术,具有丰富的界面设计和灵活的客户端功能。在某些场景下,WPF 应用需与 Windows 服务交互以实现后台任务处理、系统监控等功能。本文探讨了两者交互的方法,并通过示例代码展示了如何扩展 WPF 应用的功能。首先介绍了 Windows 服务的基础知识,然后阐述了创建 Windows 服务、设计通信接口及 WPF 客户端调用服务的具体步骤。通过合理的交互设计,WPF 应用可获得更强的后台处理能力和系统级操作权限,提升应用的整体性能。
106 0
|
3月前
|
前端开发 C# 容器
WPF/C#:实现导航功能
WPF/C#:实现导航功能
69 0
|
开发框架 前端开发 JavaScript
WPF+ASP.NET SignalR实现简易在线聊天功能
WPF+ASP.NET SignalR实现简易在线聊天功能
210 0
|
自然语言处理 编译器 C#
【WPF】实现动态切换语言(国际化)以及动态换肤功能
以下内容,手把手从搭建到最终实现,完成多语言切换以及换装功能。
446 0
【WPF】实现动态切换语言(国际化)以及动态换肤功能
|
前端开发 C# 图形学
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
Wpf开发过程中,最经常使用的功能之一,就是用户控件(UserControl)了。用户控件可以用于开发用户自己的控件进行使用,甚至可以用于打造一套属于自己的UI框架。依赖属性(DependencyProperty)是为用户控件提供可支持双向绑定的必备技巧之一,同样用处也非常广泛。
939 0
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
|
C#
WPF中使用AxisAngleRotation3D实现CAD的2D旋转功能
原文:WPF中使用AxisAngleRotation3D实现CAD的2D旋转功能       对于CAD图形来说,3D旋转比较常用,具体实现方法在上篇文章《WPF中3D旋转的实现 》中做了讲解,可以参考Daniel。
1216 0