Making AvalonEdit MVVM compatible

前端 未结 3 866
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-13 05:09

I\'m trying to make Avalon MVVM compatible in my WPF application. From googling, I found out that AvalonEdit is not MVVM friendly and I need to export the state of AvalonEdi

3条回答
  •  [愿得一人]
    2020-12-13 05:27

    Herr Grunwald is talking about wrapping the TextEditor properties with dependency properties, so that you can bind to them. The basic idea is like this (using the CaretOffset property for example):

    Modified TextEditor class

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

    Now that the CaretOffset has been wrapped in a DependencyProperty, you can bind it to a property, say Offset in your View Model. For illustration, bind a Slider control's value to the same View Model property Offset, and see that when you move the Slider, the Avalon editor's cursor position gets updated:

    Test XAML

    
      
        
        
        
        
      
    
    

    Test Code-behind

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

    Test View Model

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

提交回复
热议问题