首页 > 其他分享 >WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能

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

时间:2023-02-06 10:32:28浏览次数:52  
标签:高亮 自定义 AvalonEdit 搜索 result WPF renderer


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

文章目录

  • ​​AvlonEdit控件​​
  • ​​实现自定义高亮显示​​
  • ​​实现文本搜索​​
  • ​​实现文本替换​​
  • ​​自定义搜索栏用户控件​​
  • ​​实现自定义搜索​​
  • ​​实现自定义替换​​

AvlonEdit控件

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

WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能_开发语言

​AvalonEdit项目官网​

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

实现自定义高亮显示

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

<?xml version="1.0"?>
<SyntaxDefinition name="Custom Highlighting" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<!--设置颜色与文本风格,如粗体,背景色等-->
<Color name="Comment" foreground="#C6B1B1" exampleText="* comment"/>
<Color name="Card" fontWeight="bold" foreground="#960092" exampleText="=CSTR"/>
<Color name="Field" fontWeight="bold" foreground="#3A76D7" exampleText="CA"/>
<!-- 主要的规则集 -->
<RuleSet>
<!--以//开头或者包裹在/*..*/中的文本使用Comment颜色-->
<Span color="Comment" begin="//" />
<Span color="Comment" multiline="true" begin="/\*" end="\*/" />

<Span color="String">
<Begin>"</Begin>
<End>"</End>
<!--可以定义规则子集-->
<RuleSet>
<Span begin="\\" end="." />
</RuleSet>
</Span>
<!--定义关键词-->
<Keywords fontWeight="bold" foreground="Blue">
<Word>if</Word>
<Word>else</Word>
<!-- ... -->
</Keywords>
<!-- 可以使用正则进行定义 -->
<Rule foreground="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文件后,一定要设置文件的属性

WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能_开发语言_02

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

//注册自定义高亮
IHighlightingDefinition customHighlighting;
using (Stream s = typeof(MainWindow).Assembly.GetManifestResourceStream("NotConvertPeps.PEPSHighlighting.xshd"))
{
using (XmlReader reader = new XmlTextReader(s))
{
customHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance);
}
}
//要设置一个后缀名字,在这里我设置了fre
HighlightingManager.Instance.RegisterHighlighting("Custom Highlighting", new string[] { ".fre" }, customHighlighting);

InitializeComponent();
//在InitializeComponent()之后使用,为txtEdit设置高亮语法
txtEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(".fre");

设置完成后,看下效果

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

实现文本搜索

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

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

实现文本替换

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

自定义搜索栏用户控件

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

WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能_开发语言_05

其中注册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#代码

SearchResultBackgroundRenderer renderer = new SearchResultBackgroundRenderer();
void DoFind()
{
renderer.CurrentResults.Clear();//清空已经搜索出的结果
if (!string.IsNullOrEmpty(replaceUserControl.findContent))
{
//文字的背景高亮
textArea.TextView.BackgroundRenderers.Clear();
textArea.TextView.BackgroundRenderers.Add(renderer);
//搜索的管件方法
ISearchStrategy strategy = SearchStrategyFactory.Create(replaceUserControl.findContent, !replaceUserControl.CareCase, replaceUserControl.MatchAll, replaceUserControl.regex ? SearchMode.RegEx : SearchMode.Normal);
var results = strategy.FindAll(textArea.Document, 0, textArea.Document.TextLength);
//将搜索的结果全部加到renderer.CurrentResults中,方便后续的进行上一个、下一个搜索的展示
foreach (SearchResult result in results)
{
renderer.CurrentResults.Add(result);
}
}
}

实现下一个

private void FindNext(object sender, RoutedEventArgs e)
{
DoFind();

SearchResult result = renderer.CurrentResults.FindFirstSegmentWithStartAfter(textArea.Caret.Offset + 1);
if (result == null)
result = renderer.CurrentResults.FirstSegment;
if (result != null)
{
SelectResult(result);
}
}

实现上一个

private void FindPre(object sender, RoutedEventArgs e)
{
DoFind();
SearchResult result = 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);
}
}

实现效果

WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能_开发语言_06

实现自定义替换

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

private void ReplaceNext(object sender, RoutedEventArgs e)
{
string replace = replaceUserControl.replaceContent;
DoFind();
SearchResult result = 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实现代码高亮显示、搜索、替换功能_ui_07

文章目录

  • ​​AvlonEdit控件​​
  • ​​实现自定义高亮显示​​
  • ​​实现文本搜索​​
  • ​​实现文本替换​​
  • ​​自定义搜索栏用户控件​​
  • ​​实现自定义搜索​​
  • ​​实现自定义替换​​


标签:高亮,自定义,AvalonEdit,搜索,result,WPF,renderer
From: https://blog.51cto.com/u_15943685/6038720

相关文章

  • 用Wpf做一个Diagram画板(续2)(包含封装一个控件FlowchartEditor)
    据上一次更新https://www.cnblogs.com/akwkevin/p/15047453.html已经1年有余,本次更新主要参照了一个Blazor的Diagram的画线算法,链接地址:https://github.com/Blazor-Diagra......
  • markdown公式高亮
    前提条件需要\(markdown\)编辑器支持并开启====扩展语法,以及数学公式支持行内公式\(\sum_{i=1}^na_i\)==$\sum_{i=1}^na_i$==这种方法只能高亮行内公式,不能高......
  • WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能
    WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能很多工程软件拥有自己定义的脚本语言,作为程序员用惯了具有高亮显示和智能提示功能的编辑器,所以针对特定的脚本自己开......
  • wpf中Interaction.Behaviors详解
    在WPF4.0中,引入了一个比较实用的库——Interactions,这个库主要是通过附加属性来对UI控件注入一些新的功能,除了内置了一系列比较好用的功能外,还提供了比较良好的扩展接口。......
  • WPF调用winfrom控件
    1.导包在引用处添加System.Windows.Fotms和WindowsFormslntegration2.xaml部分在需要使用控件的页面添加引用xmlns:wf="clr-namespace:System.Windows.Forms;assembly=......
  • WPF有用的最基础整理
    日常使用最多的控件有6类:1.布局控件:可以容纳多个控件或嵌套其他布局控件,例如Grid、StackPanel、DockPanel等,有共同的父类Panel2.内容控件:只能容纳一个其他控件或布局......
  • 【gRPC】.NET 6 WPF gRPC client 无法找到命名空间生成项目失败
    基于.NET6的WPF项目作为gRPC客户端,生成项目时出错:1>D:\projects\aasp_pc_soft\AutonomicAnalysisSystemForPressurePellets\AutoAnalysisSystemClientTest\AutoAnalysis......
  • WPF控件模板查看
    背景在使用WPF的过程中,经常需要对控件的外观进行定制,这个时候查看其原有的样式或者模板进行参考就很有必要了。这样一能够减少许多工作,只修改需要的部分,二能够避免修改模......
  • ASP.Net 8将提供路由语法高亮提示
    .NET8将为所有路由提供路由语法高亮显示,包括minimalAPI、MVC、WebAPI、Razor页面和Blazor中的路由。路由语法高亮显示依赖于在代码库中应用的StringSyntax属性......
  • Revit二次开发针对类库项目中WPF界面如何引用第三方控件库HandyControl的方法
    起因是当使用类库作为WPF界面的项目时,项目中没有App.xaml,也就导致没有办法在全局资源中统一设置HandyControl的资源。解决方案很简单安装完HandyControl库后,在Window中加......