2011-09-01 141 views
4

我疯狂地使用自定义的依赖属性。我已经在这里检查了大量线程,但还没有找到任何解决方案。我想要做的是如果源提供特定的值(给定示例为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不适合我。

任何想法,我不在这里?

回答

6

你只需要设置绑定到双向,它会工作。但随着这应该是默认的,你可以根据使用下面的元数据属性寄存器:

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

获得表达的TextChanged处理程序和更新源手动不需要那么我会删除该代码。


如果没有明确设置绑定默认的模式将被使用,从the documentation

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

+0

不错!如果可以的话,会超过+1!有一个自定义用户控件,其属性绑定到子控件属性中,但不会将值传递给演示者。正在看各种各样的东西。讨厌wpf有多少魔法标志,但是它在工作的时候很棒! –

+0

很高兴帮助,是的,有很多知道,但它确实是一个很好的框架,如果它的工作:) –

+0

谢谢,这个答案救了我这么多时间。 – Orwel

0

正如你写道:“记住:我需要一个双向绑定”,所以:

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