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 ...
随机推荐
- libevent源码学习(13):事件主循环event_base_loop
目录开启事件主循环执行事件主循环校对时间 阻塞/非阻塞处理激活队列中的event事件主循环的退出event_base_loopexitevent_base_loopbreak开启事件主循环 ...
- Nginx中配置反向代理的proxy_pass的不同斜杠的区别
location /api1/ { proxy_pass http://localhost:8080; } # http://localhost/api1/xxx -> http://local ...
- JAVA获取某个月(当月)第一天的开始时刻和某个月(当月)最后一天的最后时刻
package com.date; import java.text.SimpleDateFormat; import java.util.Calendar; public class Test { ...
- ubuntu查系统信息及系统服务
系统信息 uname -a # 查看内核/操作系统/CPU信息 cat /etc/issue # 查看操作系统版本 cat /proc/version ...
- 【LeetCode】69. Sqrt(x) 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:库函数 方法二:牛顿法 方法三:二分查找 日 ...
- 【LeetCode】319. Bulb Switcher 解题报告(Python)
[LeetCode]319. Bulb Switcher 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/bulb ...
- BP网络简单实现
目录 BP算法的简单实现 Linear 全连接层 ReLu MSELoss 交叉熵损失函数 BP算法的简单实现 """ BPnet 简易实现 约定输入数据维度为(N, i ...
- [炼丹术]使用Pytorch搭建模型的步骤及教程
使用Pytorch搭建模型的步骤及教程 我们知道,模型有一个特定的生命周期,了解这个为数据集建模和理解 PyTorch API 提供了指导方向.我们可以根据生命周期的每一个步骤进行设计和优化,同时更加 ...
- Spring企业级程序设计 • 【第7章 Spring框架整合】
全部章节 >>>> 本章目录 7.1 模型数据解析及控制器返回值 7.1.1 SSM框架环境搭建 7.1.1 ModelAndView多种用法 7.1.2 整合MyBati ...
- 编写Java程序,遍历所有英雄信息(美和易思JDBC,PreparedStatement执行查询语句练习习题)
返回本章节 返回作业目录 需求说明: 继续完善英雄信息系统.使用JDBC技术,通过PreparedStatement对象的executeQuery()方法获取表示所有英雄数据的ResultSet结果集 ...