WPF学习笔记(四):AvalonEdit 代码高亮编辑控件专题
AvalonEdit 是一个基于 WPF 的文本编辑器组件。它是由 Daniel Grunwald 为 SharpDevelop 编写的。从 5.0 版开始,AvalonEdit 根据MIT许可证发布。

通过使用 AvalonEdit ,小伙伴们可以很容易的在自己的程序中集成代码编辑器。AvalonEdit 在路遥工具箱中有着广泛的运用。
安装 AvalonEdit
首先,通过 NuGet 安装 AvalonEdit ,地址是:https://www.nuget.org/packages/AvalonEdit 。
接着将以下代码粘贴到 XAML 文件中,即可创建一个最简单的 AvalonEdit 控件:
<avalonEdit:TextEditor
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
Name="TextEditor"
SyntaxHighlighting="C#"
FontFamily="Consolas"
FontSize="10pt"
LineNumbersForeground="Black"
ShowLineNumbers="True">
</avalonEdit:TextEditor>
第二行的 xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit" 是 AvalonEdit 的命名空间,属于硬编码。
AvalonEdit 内置了多种语法高亮规则,SyntaxHighlighting="C#" 的意思是对 C# 进行代码高亮。如果需要对 XML 代码进行高亮,仅需将 C# 改为 XML 即可:SyntaxHighlighting="XML" 。
第九行的 ShowLineNumbers="True" 代表展示每行的行号,这在展示单行过长的文字时非常有用,默认为 False 。
使用 JetBrand Mono 字体展示代码
JetBrand Mono 字体非常适合用来展示代码,且该字体文件非常小巧(仅有 200K 左右),可以直接嵌入在应用中。
首先,将下载到的 JetBrand Mono 字体文件 JetBrainsMono.ttf 复制到项目的 Resources 文件夹,设置文件的”生成操作“为”资源“。
接着设置 TextEditor 的 FontFamily 属性即可:
pack://application:,,,/{程序集名称};component/Resources/#JetBrains Mono
其中,{程序集名称} 需要替换为你自己的应用程序信息。
对 AvalonEdit 进行 MVVM 绑定
我们可以通过 TextEditor 的 Text 属性来获取或设置代码编辑器中的内容,但该属性不是一个依赖属性,所以我们不能直接将其绑定到 ViewModel 上。
一个针对 AvalonEdit 的 Behavior 可以协助解决该问题:
using ICSharpCode.AvalonEdit;
using Microsoft.Xaml.Behaviors;
using System;
using System.Windows;
public sealed class AvalonEditBehaviour : Behavior<TextEditor>
{
public static readonly DependencyProperty CodeTextProperty =
DependencyProperty.Register("CodeText", typeof(string), typeof(AvalonEditBehaviour),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PropertyChangedCallback));
public string CodeText
{
get { return (string)GetValue(CodeTextProperty); }
set { SetValue(CodeTextProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
if (AssociatedObject != null)
AssociatedObject.TextChanged += AssociatedObjectOnTextChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
if (AssociatedObject != null)
AssociatedObject.TextChanged -= AssociatedObjectOnTextChanged;
}
private void AssociatedObjectOnTextChanged(object sender, EventArgs eventArgs)
{
if (sender is TextEditor textEditor)
{
if (textEditor.Document != null)
CodeText = textEditor.Document.Text;
}
}
private static void PropertyChangedCallback(
DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var behavior = dependencyObject as AvalonEditBehaviour;
if (behavior.AssociatedObject != null)
{
var editor = behavior.AssociatedObject;
if (editor.Document != null)
{
var caretOffset = editor.CaretOffset;
editor.Document.Text = dependencyPropertyChangedEventArgs.NewValue.ToString();
if (caretOffset <= editor.Document.Text.Length) editor.CaretOffset = caretOffset;
}
}
}
}
假设上述代码存在于 Behaviors 命名空间下,且 ViewModel 有一个名为 Code 的通知属性。则 XAML 代码如下:
<avalonEdit:TextEditor xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit">
<i:Interaction.Behaviors xmlns:i="http://schemas.microsoft.com/xaml/behaviors">
<bh:AvalonEditBehaviour xmlns:bh="clr-namespace:Behaviors" CodeText="{Binding Code}"/>
</i:Interaction.Behaviors>
</avalonEdit:TextEditor>
开启快速搜索框
在使用 ILSpy 查看程序集源代码时,可以通过快捷键 ” CTRL + F “ 打开一个快速搜索框,要搜索的文字会高亮显示,同时支持对搜索结果进行导航:
ILSpy 的快速搜索功能
事实上 ILSpy 使用的也是 AvalonEdit 控件,开启搜索面板仅需一行代码:
ICSharpCode.AvalonEdit.Search.SearchPanel.Install(TextEditor);
以上代码在 XAML 的后置代码构造函数中 InitializeComponent 方法后调用即可。
代码折叠功能
代码折叠是一些文本编辑器,源代码编辑器和IDE的一个功能,它允许用户有选择地隐藏和显示 – “折叠” – 当前编辑文件的各个部分作为例行编辑操作的一部分。 这允许用户管理大量文本,同时仅查看在任何给定时间特别相关的文本子部分。
路遥工具箱的代码折叠功能
针对 XML 语言的代码折叠,需要用到 FlodingManager 和 XmlFoldingStrategy 。
<avalonedit:TextEditor SyntaxHighlighting="XML" TextChanged="CodeEditor_TextChanged" ShowLineNumbers="True" WordWrap="True" x:Name="CodeEditor">
<avalonedit:TextEditor.ContextMenu>
<ContextMenu>
<MenuItem Header="全部折叠" x:Name="CloseMenuItem" Click="CloseMenuItem_Click"></MenuItem>
<MenuItem Header="全部展开" x:Name="OpenMenuItem" Click="OpenMenuItem_Click"></MenuItem>
</ContextMenu>
</avalonedit:TextEditor.ContextMenu>
</avalonedit:TextEditor>
对应的后置代码如下:
using ICSharpCode.AvalonEdit.Folding;
using System;
using System.Windows;
using System.Windows.Controls;
public MyUserControl() //构造函数
{
InitializeComponent();
foldingManager = FoldingManager.Install(CodeEditor.TextArea);
}
FoldingManager foldingManager = null;
XmlFoldingStrategy foldingStrategy = new XmlFoldingStrategy();
private void CodeEditor_TextChanged(object sender, EventArgs e)
{
if (foldingManager == null) return;
foldingStrategy.UpdateFoldings(foldingManager, CodeEditor.Document);
}
private void CloseMenuItem_Click(object sender, RoutedEventArgs e)
{
if (foldingManager == null) return;
var isFrist = true;
foreach (var item in foldingManager.AllFoldings)
{
if (isFrist)
{
isFrist = false;
continue;
}
item.IsFolded = true;
}
}
private void OpenMenuItem_Click(object sender, RoutedEventArgs e)
{
if (foldingManager == null) return;
foreach (var item in foldingManager.AllFoldings)
{
item.IsFolded = false;
}
}
结束
以上就是本片的全部内容,本文展示的所有代码均可以在路遥工具箱中找到运用。
WPF学习笔记(四):AvalonEdit 代码高亮编辑控件专题的更多相关文章
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- .NET MVC 学习笔记(七)— 控制input控件
.NET MVC 学习笔记(七)— 控制input控件 画面中有时候需要输入数字,这时就需要控制input的输入.以下为保留两位有效数字. /* * 初始化数字输入 */ function initD ...
- Winform控件学习笔记【第二天】——常用控件
背景:期末考试刚过就感冒了,嗓子火辣辣的,好难受.但是一想起要学习总结就打起精神来了,Winform控件网上也没有多少使用教程,大部分都是自己在网上零零散散的学的,大部分用的熟了,不总结会很容易忘得. ...
- WPF学习笔记四之命令
1.概念 对于程序来说,命令就是一个个任务,例如保存,复制,剪切这些操作都可以理解为一个个命令.即当我们点击一个复杂按钮时,此时就相当于发出了一个复制的命令,即告诉文本框执行一个复杂选中内容的操作,然 ...
- 【WPF学习】第二十二章 文本控件
WPF提供了三个用于输入文本的控件:TextBox.RichTextBox和PasswordBox.PasswordBox控件直接继承自Control类.TextBox和RichTextBox控件间接 ...
- Android学习笔记(九)——布局和控件的自定义
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! View是 Android中一种最基本的 UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件 ...
- Dynamic CRM 2013学习笔记(八)过滤查找控件 (类似省市联动)
我们经常要实现类似省市联动一样的功能,常见的就是二个查找控件,一个选择了省后,另一个市的查找控件就自动过滤了,只显示当前省下的市,而不是所有的市.当然这是最简单的,实际工作中还有更复杂的功能要通过过滤 ...
- 【AngularJS学习笔记】封装一些简单的控件(封装成Html标签)
bootstrap有强大的指令系统,可以自定义一些属性,基本知识请移步:http://angularjs.cn/A00r http://www.cnblogs.com/lvdabao/p/33916 ...
- WPF学习之路(十二)控件(HeaderedContent控件)
GroupBox 用来组织多种控件的常见控件,因为是内容空间,只能直接包含一项,需要使用面板一类的中间空间. Header和Content可以是任意元素 <GroupBox> <Gr ...
随机推荐
- vue+el-element中根据文件名动态创建dialog的方法
背景 在项目中使用对话框的通常做法是把对话框封装成组件,在使用的地方引入,然后添加到template,使用visible.sync控制对话框的显示/隐藏,监听confirm事件处理用户点击确定.如下: ...
- C语言读写二进制文件
fseek用法 fseek用来移动文件指针.函数原型 int fseek(FILE * stream, long offset, int fromwhere); 参数解释: stream 是文件流指针 ...
- 【LeetCode】974. Subarray Sums Divisible by K 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 前缀和求余 日期 题目地址:https:/ ...
- 【LeetCode】859. Buddy Strings 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 日期 题目地址:https://leetcod ...
- 【剑指Offer】翻转单词顺序列 解题报告(Python)
[剑指Offer]翻转单词顺序列 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...
- Pebbles(hdu2167)
Pebbles Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- P1547逆转,然后再见
描述 上届的高三在这个暑假终于要到各个城市奔向他们的大学生活了.奇怪的是学校这次异常阔气,说要用三台车子去载他们上学.上届高三的师兄们异常兴奋--可惜的是临行的时候,学校终于露出它"狰狞&q ...
- AlexNet: ImageNet Classification with Deep Convolutional Neural Networks
目录 激活函数 防止过拟合 增加数据 Dropout 细节 代码 AlexNet 上图是论文的网络的结构图,包括5个卷积层和3个全连接层,作者还特别强调,depth的重要性,少一层结果就会变差,所以这 ...
- 以简御繁介绍IOC
1.IOC的理论背景 大家开发理念,一直都是奔着架构稳定.低耦合性.而IOC初衷,就是为了解决模块依赖问题,理解<六大设计原则(SOLID)> 如图所示,在我们开发中,业务的实现,就是靠着 ...
- Eclipse导入Zookeeper源码Version2017.11.3
将Zookeeper源码导入Eclipse, Zookeeper源码需要使用ant构建后才能导入Eclipse, 和Solr的源码一样也是使用ant构建的, 大部分可以参考Eclipse导入Solr源 ...