WPF学习笔记(四):AvalonEdit 代码高亮编辑控件专题
AvalonEdit 是一个基于 WPF 的文本编辑器组件。它是由 Daniel Grunwald 为 SharpDevelop 编写的。从 5.0 版开始,AvalonEdit 根据MIT许可证发布。
通过使用 AvalonEdit ,小伙伴们可以很容易的在自己的程序中集成代码编辑器。AvalonEdit 在路遥工具箱中有着广泛的运用。
安装 AvalonEdit
首先,通过 NuGet 安装 AvalonEdit ,地址是:https://域名/packages/AvalonEdit 。
接着将以下代码粘贴到 XAML 文件中,即可创建一个最简单的 AvalonEdit 控件:
<avalonEdit:TextEditor
xmlns:avalonEdit="http://域名/sharpdevelop/avalonedit"
Name="TextEditor"
SyntaxHighlighting="C#"
FontFamily="Consolas"
FontSize="10pt"
LineNumbersForeground="Black"
ShowLineNumbers="True">
</avalonEdit:TextEditor>
第二行的 xmlns:avalonEdit="http://域名/sharpdevelop/avalonedit"
是 AvalonEdit 的命名空间,属于硬编码。
AvalonEdit 内置了多种语法高亮规则,SyntaxHighlighting="C#"
的意思是对 C# 进行代码高亮。如果需要对 XML 代码进行高亮,仅需将 C# 改为 XML 即可:SyntaxHighlighting="XML"
。
第九行的 ShowLineNumbers="True"
代表展示每行的行号,这在展示单行过长的文字时非常有用,默认为 False 。
使用 JetBrand Mono 字体展示代码
JetBrand Mono 字体非常适合用来展示代码,且该字体文件非常小巧(仅有 200K 左右),可以直接嵌入在应用中。
首先,将下载到的 JetBrand Mono 字体文件 域名 复制到项目的 Resources 文件夹,设置文件的”生成操作“为”资源“。
接着设置 TextEditor 的 FontFamily 属性即可:
pack://application:,,,/{程序集名称};component/Resources/#JetBrains Mono
其中,{程序集名称}
需要替换为你自己的应用程序信息。
对 AvalonEdit 进行 MVVM 绑定
我们可以通过 TextEditor 的 Text 属性来获取或设置代码编辑器中的内容,但该属性不是一个依赖属性,所以我们不能直接将其绑定到 ViewModel 上。
一个针对 AvalonEdit 的 Behavior 可以协助解决该问题:
using 域名onEdit;
using 域名viors;
using System;
using 域名ows;
public sealed class AvalonEditBehaviour : Behavior<TextEditor>
{
public static readonly DependencyProperty CodeTextProperty =
域名ster("CodeText", typeof(string), typeof(AvalonEditBehaviour),
new FrameworkPropertyMetadata(default(string), 域名sTwoWayByDefault, PropertyChangedCallback));
public string CodeText
{
get { return (string)GetValue(CodeTextProperty); }
set { SetValue(CodeTextProperty, value); }
}
protected override void OnAttached()
{
域名tached();
if (AssociatedObject != null)
域名Changed += AssociatedObjectOnTextChanged;
}
protected override void OnDetaching()
{
域名taching();
if (AssociatedObject != null)
域名Changed -= AssociatedObjectOnTextChanged;
}
private void AssociatedObjectOnTextChanged(object sender, EventArgs eventArgs)
{
if (sender is TextEditor textEditor)
{
if (域名ment != null)
CodeText = 域名;
}
}
private static void PropertyChangedCallback(
DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var behavior = dependencyObject as AvalonEditBehaviour;
if (域名ciatedObject != null)
{
var editor = 域名ciatedObject;
if (域名ment != null)
{
var caretOffset = 域名tOffset;
域名 = 域名ring();
if (caretOffset <= 域名.Length) 域名tOffset = caretOffset;
}
}
}
}
假设上述代码存在于 Behaviors 命名空间下,且 ViewModel 有一个名为 Code 的通知属性。则 XAML 代码如下:
<avalonEdit:TextEditor xmlns:avalonEdit="http://域名/sharpdevelop/avalonedit">
<i:域名viors xmlns:i="http://域名/xaml/behaviors">
<bh:AvalonEditBehaviour xmlns:bh="clr-namespace:Behaviors" CodeText="{Binding Code}"/>
</i:域名viors>
</avalonEdit:TextEditor>
开启快速搜索框
在使用 ILSpy 查看程序集源代码时,可以通过快捷键 ” CTRL + F “ 打开一个快速搜索框,要搜索的文字会高亮显示,同时支持对搜索结果进行导航:
ILSpy 的快速搜索功能
事实上 ILSpy 使用的也是 AvalonEdit 控件,开启搜索面板仅需一行代码:
域名域名all(TextEditor);
以上代码在 XAML 的后置代码构造函数中 InitializeComponent
方法后调用即可。
代码折叠功能
代码折叠是一些文本编辑器,源代码编辑器和IDE的一个功能,它允许用户有选择地隐藏和显示 – “折叠” – 当前编辑文件的各个部分作为例行编辑操作的一部分。 这允许用户管理大量文本,同时仅查看在任何给定时间特别相关的文本子部分。
路遥工具箱的代码折叠功能
针对 XML 语言的代码折叠,需要用到 FlodingManager 和 XmlFoldingStrategy 。
<avalonedit:TextEditor SyntaxHighlighting="XML" TextChanged="CodeEditor_TextChanged" ShowLineNumbers="True" WordWrap="True" x:Name="CodeEditor">
<avalonedit:域名extMenu>
<ContextMenu>
<MenuItem Header="全部折叠" x:Name="CloseMenuItem" Click="CloseMenuItem_Click"></MenuItem>
<MenuItem Header="全部展开" x:Name="OpenMenuItem" Click="OpenMenuItem_Click"></MenuItem>
</ContextMenu>
</avalonedit:域名extMenu>
</avalonedit:TextEditor>
对应的后置代码如下:
using 域名ing;
using System;
using 域名ows;
using 域名rols;
public MyUserControl() //构造函数
{
InitializeComponent();
foldingManager = 域名all(域名Area);
}
FoldingManager foldingManager = null;
XmlFoldingStrategy foldingStrategy = new XmlFoldingStrategy();
private void CodeEditor_TextChanged(object sender, EventArgs e)
{
if (foldingManager == null) return;
域名teFoldings(foldingManager, 域名ment);
}
private void CloseMenuItem_Click(object sender, RoutedEventArgs e)
{
if (foldingManager == null) return;
var isFrist = true;
foreach (var item in 域名oldings)
{
if (isFrist)
{
isFrist = false;
continue;
}
域名lded = true;
}
}
private void OpenMenuItem_Click(object sender, RoutedEventArgs e)
{
if (foldingManager == null) return;
foreach (var item in 域名oldings)
{
域名lded = false;
}
}
结束
以上就是本片的全部内容,本文展示的所有代码均可以在路遥工具箱中找到运用。