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 ...
随机推荐
- 源码-DbUtil.java
package com.tetralogy.util; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.D ...
- 分享 NET 5.x 自定义文件日志实现 原汁原味
下面直接贴出实现代码 FileLoggerProvider /// <summary> /// 文件记录器提供商 /// </summary> public class Fil ...
- 【LeetCode】940. Distinct Subsequences II 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...
- Hive SQL优化思路
Hive的优化主要分为:配置优化.SQL语句优化.任务优化等方案.其中在开发过程中主要涉及到的可能是SQL优化这块. 优化的核心思想是: 减少数据量(例如分区.列剪裁) 避免数据倾斜(例如加参数.Ke ...
- 手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏01游戏窗口
项目源码 项目源码 游戏配置信息类 Config.java 没什么解释的. package config; public class Config { public final static Stri ...
- Tomcat 组成与工作原理
开源的 Java Web 应用服务器,实现了 Java EE(Java Platform Enterprise Edition)的部分技术规范,比如 Java Servlet.Java Server ...
- MySQL 中的共享表空间与独立表空间
对于 InnoDB 存储引擎来说,它可以将每张表存放于独立的表空间,即tablename.ibd 文件:也可以将数据存放于 ibdata 的共享表空间,一般命名是 ibdataX,后面的 X 是一个具 ...
- 「算法笔记」FHQ-Treap
右转→https://www.cnblogs.com/mytqwqq/p/15057231.html 下面放个板子 (禁止莱莱白嫖板子) P3369 [模板]普通平衡树 #include<bit ...
- Sublime Text 3菜单栏隐藏后怎么显示
Sublime Text 3如何显示菜单栏 今天在使用Sublime Text 3敲代码的时候不小心就把上侧的菜单栏隐藏了,自己鼓捣了半天才把菜单栏弄出来,下面我就给大家讲解一下我是如何操作的 键盘按 ...
- matplotlib 进阶之Artist tutorial(如何操作Atrist和定制)
目录 基本 plt.figure() fig.add_axes() ax.lines set_xlabel 一个完整的例子 定制你的对象 obj.set(alpha=0.5, zorder=2), o ...