双向绑定到AvalonEdit文档文本使用MVVM [英] Two Way Binding to AvalonEdit Document Text using MVVM

查看:2095
本文介绍了双向绑定到AvalonEdit文档文本使用MVVM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想包括AvalonEdit 文本编辑控制到我的MVVM的应用程序。我需要的第一件事情是能够绑定到 TextEditor.Text 属性,这样我可以显示文本。要做到这一点我按照和例子,在给制作AvalonEdit MVVM兼容 。现在,我已经实现了使用公认的答案下面的类为模板

I want to include an AvalonEdit TextEditor control into my MVVM application. The first thing I require is to be able to bind to the TextEditor.Text property so that I can display text. To do this I have followed and example that was given in Making AvalonEdit MVVM compatible. Now, I have implemented the following class using the accepted answer as a template

public sealed class MvvmTextEditor : TextEditor, INotifyPropertyChanged
{
    public static readonly DependencyProperty TextProperty =
         DependencyProperty.Register("Text", typeof(string), typeof(MvvmTextEditor),
         new PropertyMetadata((obj, args) =>
             {
                 MvvmTextEditor target = (MvvmTextEditor)obj;
                 target.Text = (string)args.NewValue;
             })
        );

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

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

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

当XAML是

<Controls:MvvmTextEditor HorizontalAlignment="Stretch"
                         VerticalAlignment="Stretch"
                         FontFamily="Consolas"
                         FontSize="9pt" 
                         Margin="2,2" 
                         Text="{Binding Text, NotifyOnSourceUpdated=True, Mode=TwoWay}"/>

首先,这是行不通的。绑定是不是在所有的史努比所示(不红,没有什么,其实我甚至不能看到文本依赖属性)。

我已经看到了这个问题,这也正是我的一样<一个href=\"http://stackoverflow.com/questions/14855304/two-way-binding-in-avalonedit-doesnt-work/14863468#comment27995064_14863468\">Two-way在AvalonEdit绑定不起作用,但接受的答案确实的的工作(至少对我来说)。所以我的问题是:

I have seen this question which is exactly the same as mine Two-way binding in AvalonEdit doesn't work but the accepted answer does not work (at least for me). So my question is:

我如何就可以使用上面的方法和双向绑定什么是正确执行我的 MvvmTextEditor 类的?

How can I perform two way binding using the above method and what is the correct implementation of my MvvmTextEditor class?

感谢您的时间。

注:我在我的ViewModel我的文本属性,并将其实现了所需的 INotifyPropertyChanged的接口。

Note: I have my Text property in my ViewModel and it implements the required INotifyPropertyChanged interface.

推荐答案

创建类的行为,将附加TextChanged事件,将挂钩绑定到视图模型的依赖项属性。

Create a Behavior class that will attach the TextChanged event and will hook up the dependency property that is bound to the ViewModel.

AvalonTextBehavior.cs

public sealed class AvalonEditBehaviour : Behavior<TextEditor> 
{
    public static readonly DependencyProperty GiveMeTheTextProperty =
        DependencyProperty.Register("GiveMeTheText", typeof(string), typeof(AvalonEditBehaviour), 
        new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PropertyChangedCallback));

    public string GiveMeTheText
    {
        get { return (string)GetValue(GiveMeTheTextProperty); }
        set { SetValue(GiveMeTheTextProperty, 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)
    {
        var textEditor = sender as TextEditor;
        if (textEditor != null)
        {
            if (textEditor.Document != null)
                GiveMeTheText = textEditor.Document.Text;
        }
    }

    private static void PropertyChangedCallback(
        DependencyObject dependencyObject,
        DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var behavior = dependencyObject as AvalonEditBehaviour;
        if (behavior.AssociatedObject!= null)
        {
            var editor = behavior.AssociatedObject as TextEditor;
            if (editor.Document != null)
            {
                var caretOffset = editor.CaretOffset;
                editor.Document.Text = dependencyPropertyChangedEventArgs.NewValue.ToString();
                editor.CaretOffset = caretOffset;
            }
        }
    }
}

View.xaml

 <avalonedit:TextEditor
        WordWrap="True"
        ShowLineNumbers="True"
        LineNumbersForeground="Magenta"
        x:Name="textEditor"
        FontFamily="Consolas"
        SyntaxHighlighting="XML"
        FontSize="10pt">
        <i:Interaction.Behaviors>
            <controls:AvalonEditBehaviour GiveMeTheText="{Binding Test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </i:Interaction.Behaviors>
    </avalonedit:TextEditor>

其中, I 被定义为的xmlns:I =CLR的命名空间:System.Windows.Interactivity;装配= System.Windows.Interactivity

where i is defined as "xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity""

ViewModel.cs

    private string _test;
    public string Test
    {
        get { return _test; }
        set { _test = value; }
    }

这应该给你的文本,并将它推回视图模型。

That should give you the Text and push it back to the ViewModel.

这篇关于双向绑定到AvalonEdit文档文本使用MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆