基于AvalonEdit和prism的文本编辑器_AvalonEdit

AvalonEdit_文本编辑器

基于AvalonEdit和prism的文本编辑器

第一步:导入AvalonEdit包
在这里插入图片描述

第二步:编辑AvalonEditBehaviour

我们可以通过 TextEditor 的 Text 属性来获取或设置代码编辑器中的内容,但该属性不是一个依赖属性,所以我们不能直接将其绑定到 ViewModel 上。

using ICSharpCode.AvalonEdit;
using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace WPF_AvalonEdit
{
    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;
                }
            }
        }
    }

}

第三步:编写界面xaml

<Window
    x:Class="WPF_AvalonEdit.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:prism="http://prismlibrary.com/"
    Title="文本编辑器示例程序"
    Width="525"
    Height="350"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <avalonEdit:TextEditor
            xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
            x:Name="TextEditor"
            FontFamily="Consolas"
            FontSize="16px"
            LineNumbersForeground="Black"
            PreviewMouseWheel="TextEditor_PreviewMouseWheel"
            ShowLineNumbers="True"
            SyntaxHighlighting="XML"
            TextChanged="CodeEditor_TextChanged"
            WordWrap="True">
            <i:Interaction.Behaviors>
                <bh:AvalonEditBehaviour xmlns:bh="clr-namespace:WPF_AvalonEdit" CodeText="{Binding Code}" />
            </i:Interaction.Behaviors>
        </avalonEdit:TextEditor>
        
        <StackPanel Grid.Row="1">
            <Button Command="{Binding setCmd}" Content="刷新数据" />
            <Button Command="{Binding getCmd}" Content="获取数据" />
            <TextBox Text="{Binding text}" Height="129" />
        </StackPanel>
    </Grid>
</Window>

第四步:编写后台工具类

using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Folding;
using System;
using System.Windows;
using System.Windows.Input;

namespace WPF_AvalonEdit.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //代码折叠功能
            foldingManager = FoldingManager.Install(TextEditor.TextArea);
            //开启快速搜索框 快捷键"CTRL + F"
            ICSharpCode.AvalonEdit.Search.SearchPanel.Install(TextEditor);
        }
        FoldingManager foldingManager = null;
        XmlFoldingStrategy foldingStrategy = new XmlFoldingStrategy();

        private void CodeEditor_TextChanged(object sender, EventArgs e)
        {
            if (foldingManager == null) return;
            foldingStrategy.UpdateFoldings(foldingManager, TextEditor.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;
            }
        }
        //ctrl+鼠标滚轮实现文字的放大和缩小
        private void TextEditor_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            double scale = (sender as TextEditor).FontSize;
            if (Keyboard.IsKeyDown(Key.LeftCtrl))
            {
                if (e.Delta < 0)
                {
                    scale -= 1;
                }
                else
                {
                    scale += 1;
                }
                this.TextEditor.FontSize = scale;
            }
        }
    }
}

第四步:绑定事件和属性

using Prism.Commands;
using Prism.Mvvm;

namespace WPF_AvalonEdit.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        public MainWindowViewModel()
        {

        }

        private string _Code;
        public string Code
        {
            get { return _Code; }
            set { SetProperty(ref _Code, value); }
        }

        private string _text;
        public string text
        {
            get { return _text; }
            set { SetProperty(ref _text, value); }
        }

        public DelegateCommand setCmd => new DelegateCommand(() =>
        {
            Code = text;
        });

        public DelegateCommand getCmd => new DelegateCommand(() =>
        {
            text = Code;
        });
    }
}

展示效果
在这里插入图片描述

2023/3/12

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值