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;
}
}
結束
以上就是本片的全部內容,本文展示的所有代碼均可以在路遙工具箱中找到運用。