c# - 使用 MVVM 在 WPF 中绑定(bind)失败

标签 c# wpf mvvm binding avalonedit

我创建了一个继承自 AvalonEdit 的自定义 TextEditor 控件。我这样做是为了方便使用此编辑器控件使用 MVVM 和 Caliburn Micro。 [为显示目的而缩减] MvvTextEditor 类是

public class MvvmTextEditor : TextEditor, INotifyPropertyChanged
{
    public MvvmTextEditor()
    {
        TextArea.SelectionChanged += TextArea_SelectionChanged;
    }

    void TextArea_SelectionChanged(object sender, EventArgs e)
    {
        this.SelectionStart = SelectionStart;
        this.SelectionLength = SelectionLength;
    }

    public static readonly DependencyProperty SelectionLengthProperty =
         DependencyProperty.Register("SelectionLength", typeof(int), typeof(MvvmTextEditor),
         new PropertyMetadata((obj, args) =>
             {
                 MvvmTextEditor target = (MvvmTextEditor)obj;
                 target.SelectionLength = (int)args.NewValue;
             }));

    public new int SelectionLength
    {
        get { return base.SelectionLength; }
        set { SetValue(SelectionLengthProperty, value); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged([CallerMemberName] string caller = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
            PropertyChanged(this, new PropertyChangedEventArgs(caller));
    }
}

现在,在包含此控件的 View 中,我有以下 XAML:

    <Controls:MvvmTextEditor 
        Caliburn:Message.Attach="[Event TextChanged] = [Action DocumentChanged()]"
        TextLocation="{Binding TextLocation, Mode=TwoWay}"
        SyntaxHighlighting="{Binding HighlightingDefinition}" 
        SelectionLength="{Binding SelectionLength, 
                                  Mode=TwoWay, 
                                  NotifyOnSourceUpdated=True, 
                                  NotifyOnTargetUpdated=True}" 
        Document="{Binding Document, Mode=TwoWay}"/>

我的问题是 SelectionLength(和 SelectionStart 但让我们现在只考虑长度,因为问题是一样的)。如果我用鼠标选择了一些东西,从 View 到我的 View 模型的绑定(bind)效果很好。现在,我已经编写了一个查找和替换实用程序,我想设置 SelectionLength(在 中有 getset 可用TextEditor 控制)从后面的代码。在我的 View 模型中,我只是设置 SelectionLength = 50,我在 View 模型中实现了它,例如

private int selectionLength;
public int SelectionLength
{
    get { return selectionLength; }
    set
    {
        if (selectionLength == value)
            return;
        selectionLength = value;
        Console.WriteLine(String.Format("Selection Length = {0}", selectionLength));
        NotifyOfPropertyChange(() => SelectionLength);
    }
}

当我设置 SelectionLength = 50 时,DependencyProperty SelectionLengthProperty 不会在 MvvmTextEditor 类中更新,就像 TwoWay 绑定(bind)到我的控件失败,但使用 Snoop 没有任何迹象。我认为这只能通过绑定(bind)来工作,但事实并非如此。

我是否遗漏了一些简单的东西,或者我是否必须在 MvvmTextEditor 类中设置和事件处理程序,该类监听我的 View 模型中的变化并更新 DP 本身 [which提出它自己的问题]?

感谢您的宝贵时间。

最佳答案

这是因为 DependencyProperty 中的 GetterSetter 只是一个 .NET Wrapper。框架将使用 GetValueSetValue 本身。

您可以尝试从 DependencyProperty 访问 PropertyChangedCallback 并在那里设置正确的值。

 public int SelectionLength
        {
            get { return (int)GetValue(SelectionLengthProperty); }
            set { SetValue(SelectionLengthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectionLength.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectionLengthProperty =
            DependencyProperty.Register("SelectionLength", typeof(int), typeof(MvvmTextEditor), new PropertyMetadata(0,SelectionLengthPropertyChanged));


        private static void SelectionLengthPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var textEditor = obj as MvvmTextEditor;

            textEditor.SelectionLength = e.NewValue;
        }

关于c# - 使用 MVVM 在 WPF 中绑定(bind)失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23827718/

相关文章:

wpf - 可以从 MVVM 中的 View 订阅 ViewModel 的 .NET 事件吗?

c# - MVVM 创建 ViewModel

c# - 如何显示 C# 窗口服务的系统托盘图标?

c# - 最小化WPF中的窗口?

c# - 是否可以在 1 行代码内计算 : increment index by 1 and wrap back to 0 if(index > list. 计数)?

c# - (WPF) 如何使用每行中的按钮更改 listBox 中的按钮图像背景?

c# - WPF : Custom Datagrid inside combobox

wpf - 具有MVVM模式的模态窗口

c# - 基于先前排序的排序

c# - 尝试生成指定数字的所有序列,直到达到最大总和