依赖属性 - 更新源

8
我正在为自定义依赖属性烦恼不已。我已经查看了很多相关的帖子,但是还没有找到解决方案。我的目标是,如果源提供了特定的值(例如给定示例中的null),则替换属性的值。无论我尝试什么方法,在源中的属性值始终保持为null,从未更新。
这是我的自定义控件:
public class TextBoxEx : TextBox
{
    public TextBoxEx()
    {
        TrueValue = 0;
        this.TextChanged += (s, e) =>
        {
            TrueValue = Text.Length;
            SetCurrentValue(MyPropertyProperty, TrueValue);
            var x = BindingOperations.GetBindingExpression(this, MyPropertyProperty);
            if (x != null)
            {
                x.UpdateSource();
            }
        };
    }

    public int? TrueValue { get; set; }

    public int? MyProperty
    {
        get { return (int?)GetValue(MyPropertyProperty); }
        set { SetValue(MyPropertyProperty, value); }
    }

    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.Register("MyProperty", typeof(int?), typeof(TextBoxEx), new PropertyMetadata(null, PropertyChangedCallback));

    private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue == null)
        {
            d.SetCurrentValue(MyPropertyProperty, (d as TextBoxEx).TrueValue);
        }
    }
}

这是我正在绑定的 DataContext:

public class VM : INotifyPropertyChanged
{
    private int? _Bar = null;

    public int? Bar
    {
        get { return _Bar; }
        set
        {
            _Bar = value;
            OnPropertyChanged("Bar");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

我的绑定看起来像这样:

<local:TextBoxEx MyProperty="{Binding Bar, UpdateSourceTrigger=PropertyChanged}"/>

记住:我需要双向绑定,所以 OneWayToSource 对我没用。
你知道我漏掉了什么吗?
2个回答

9

您只需要将绑定设置为双向,它就可以工作。但是,由于这应该是默认值,因此您可以使用以下元数据相应地注册属性:

... new FrameworkPropertyMetadata(null,
                                  FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                  PropertyChangedCallback)

TextChanged处理程序中获取表达式并手动更新源是不必要的,因此我会删除该代码。
如果您没有在绑定上显式设置模式,则将使用默认值。从文档中可以看出:

默认值:使用绑定目标的默认Mode值。默认值因每个依赖属性而异。一般来说,可由用户编辑的控件属性(例如文本框和复选框的属性)默认为双向绑定,而大多数其他属性默认为单向绑定。通过使用GetMetadata获取属性元数据,然后检查BindsTwoWayByDefault属性的布尔值,可以以编程方式确定依赖属性默认绑定为单向还是双向。


不错!如果可以的话,我会给它+1的!我有一个自定义用户控件,将属性绑定到子控件的属性,但是没有将值传递回呈现器。我看了各种各样的东西。我讨厌在wpf中有多少神奇的标志,但当它起作用时,它很棒! - JonnyRaa
很高兴能帮到你,确实有很多需要了解的地方,但如果它能正常工作,那么这确实是一个不错的框架 :) - H.B.

0

正如你所写:“记住:我需要双向绑定”,因此:

<local:TextBoxEx MyProperty="{Binding Bar, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接