使AvalonEdit MVVM兼容

我正在尝试在我的WPF应用程序中使Avalon MVVM兼容。 从谷歌搜索,我发现AvalonEdit不是MVVM友好的 ,我需要通过创建一个派生自TextEditor的类然后添加必要的依赖属性来导出AvalonEdit的状态。 我担心格伦沃尔德先生在这里的回答让我很失落:

如果你真的需要使用MVVM导出编辑器的状态,那么我建议你创建一个派生自TextEditor的类,它添加必要的依赖属性并将它们与AvalonEdit中的实际属性同步。

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

Herr Grunwald正在讨论使用依赖项属性包装TextEditor 属性 ,以便您可以绑定它们。 基本思路是这样的(例如使用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中,您可以将它绑定到属性,例如View Model中的Offset 。 为了说明,将Slider控件的值绑定到相同的View Model属性Offset ,并看到当您移动Slider时,Avalon编辑器的光标位置会更新:

测试XAML

         

测试代码落后

 namespace AvalonDemo { public partial class TestWindow : Window { public AvalonTestModel ViewModel { get; set; } public TestWindow() { ViewModel = new AvalonTestModel(); InitializeComponent(); } } } 

测试视图模型

 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)); } } } 

您可以使用编辑器中的Document属性并将其绑定到ViewModel的属性。

以下是视图的代码:

       

以及ViewModel的代码:

 namespace AvalonEditIntegration.UI { using System.Windows; using System.Windows.Input; using ICSharpCode.AvalonEdit.Document; public class ViewModel { public ViewModel() { ShowCode = new DelegatingCommand(Show); Document = new TextDocument(); } public ICommand ShowCode { get; private set; } public TextDocument Document { get; set; } private void Show() { MessageBox.Show(Document.Text); } } } 

来源: 博客nawrem.reverse

不确定这是否符合您的需求,但我找到了一种方法来访问ViewModelTextEditor的所有“重要”组件,同时将它显示在View上,但仍在探索可能性。

我所做的不是在View上实例化TextEditor ,然后绑定我需要的许多属性,我创建了一个内容控件并将其内容绑定到我在ViewModel中创建的TextEditor实例。

视图:

  

视图模型:

 using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Highlighting; // ... private TextEditor m_AvalonEditor = new TextEditor(); public TextEditor AvalonEditor => m_AvalonEditor; 

在ViewModel中测试代码(有效!)

 // tests with the main component m_AvalonEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("XML"); m_AvalonEditor.ShowLineNumbers = true; m_AvalonEditor.Load(@"C:\testfile.xml"); // test with Options m_AvalonEditor.Options.HighlightCurrentLine = true; // test with Text Area m_AvalonEditor.TextArea.Opacity = 0.5; // test with Document m_AvalonEditor.Document.Text += "bla"; 

目前我仍在确定我需要我的应用程序配置/使用textEditor,但是从这些测试中我似乎可以在保持MVVM方法的同时更改它的任何属性。