c# - 使 AvalonEdit MVVM 兼容

标签 c# .net wpf mvvm avalonedit

我正在努力使 Avalon MVVM 在我的 WPF 应用程序中兼容。通过谷歌搜索,我发现 AvalonEdit is not MVVM friendly我需要通过创建一个从 TextEditor 派生的类然后添加必要的依赖属性来导出 AvalonEdit 的状态。恐怕我对 Herr Grunwald 的回答很迷茫 here :

If you really need to export the state of the editor using MVVM, then I suggest you create a class deriving from TextEditor which adds the necessary dependency properties and synchronizes them with the actual properties in AvalonEdit.

有没有人有关于如何实现这一目标的示例或好的建议?

最佳答案

Herr Grunwald 正在谈论用 dependency properties 包装 TextEditor 属性,以便您可以绑定(bind)到它们。基本思路是这样的(例如使用 CaretOffset 属性):

修改的TextEditor类

public class MvvmTextEditor : TextEditor, INotifyPropertyChanged
{
    public static DependencyProperty CaretOffsetProperty = 
        DependencyProperty.Register("CaretOffset", typeof(int), typeof(MvvmTextEditor),
        // binding changed callback: set value of underlying property
        new PropertyMetadata((obj, args) =>
        {
            MvvmTextEditor target = (MvvmTextEditor)obj;
            target.CaretOffset = (int)args.NewValue;
        })
    );

    public new string Text
    {
        get { return base.Text; }
        set { base.Text = value; }
    }

    public new int CaretOffset
    {
        get { return base.CaretOffset; }
        set { base.CaretOffset = value; }
    }

    public int Length { get { return base.Text.Length; } }

    protected override void OnTextChanged(EventArgs e)
    {
        RaisePropertyChanged("Length");
        base.OnTextChanged(e);
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

既然 CaretOffset 已经被包装在 DependencyProperty 中,您可以将它绑定(bind)到一个属性,比如 View 模型中的 Offset。例如,将 Slider 控件的值绑定(bind)到相同的 View 模型属性 Offset,并看到当您移动 Slider 时,Avalon 编辑器的光标位置得到更新:

测试 XAML

<Window x:Class="AvalonDemo.TestWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
    xmlns:avalonExt="clr-namespace:WpfTest.AvalonExt"
    DataContext="{Binding RelativeSource={RelativeSource Self},Path=ViewModel}">
  <StackPanel>
    <avalonExt:MvvmTextEditor Text="Hello World" CaretOffset="{Binding Offset}" x:Name="editor" />
    <Slider Minimum="0" Maximum="{Binding ElementName=editor,Path=Length,Mode=OneWay}" 
        Value="{Binding Offset}" />
    <TextBlock Text="{Binding Path=Offset,StringFormat='Caret Position is {0}'}" />
    <TextBlock Text="{Binding Path=Length,ElementName=editor,StringFormat='Length is {0}'}" />
  </StackPanel>
</Window>

测试代码隐藏

namespace AvalonDemo
{
    public partial class TestWindow : Window
    {
        public AvalonTestModel ViewModel { get; set; }

        public TestWindow()
        {
            ViewModel = new AvalonTestModel();
            InitializeComponent();
        }
    }
}

测试 View 模型

public class AvalonTestModel : INotifyPropertyChanged
{
    private int _offset;

    public int Offset 
    { 
        get { return _offset; } 
        set 
        { 
            _offset = value; 
            RaisePropertyChanged("Offset"); 
        } 
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

关于c# - 使 AvalonEdit MVVM 兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12344367/

相关文章:

c# - 如何修复 Viewstate 中表的序列化?

c# - List<Object> 上的 Parallel.ForEach 线程安全

c# - 将 TextBox 绑定(bind)到设置不起作用

c# - WPF 错误 : Property elements cannot be in the middle of an element's content. 它们必须在内容之前或之后

wpf - 如何将 WPF xaml 表单的 Design DataContext 设置为使用泛型类型参数的类

c# - C#中的printf是什么

c# - 如何在 C# 中列出具有特定日期模式的所有子目录

c# - 通过 C# 调用 Win32 api 失败!

.net - 等待异步模式和工作窃取线程

c# - 从 C# 动态类型调用 `Contains` 方法会产生错误 - 为什么?