无法数据绑定DependencyProperty

时间:2009-10-14 14:06:40

标签: wpf data-binding dependency-properties

我有一个带有DependencyProperty的UserControl。我使用数据绑定表达式在主机窗口中设置它的值。但是,它没有按预期工作。

来自用户控件的代码隐藏的片段:

public class ViewBase : UserControl
{
    public static readonly DependencyProperty ViewModelProperty
        = DependencyProperty.Register(
            "ViewModel", typeof(ViewModelBase), typeof(ViewBase));

    public ViewModelBase ViewModel
    {
        get { return GetValue(ViewModelProperty) as ViewModelBase; }
        set
        {
            SetValue(ViewModelProperty, value);
        }
    }
}

从XAML(注意:CasingListView继承自ViewBase):

<CasingEditor:CasingListView x:Name="_casingListView"
                             ViewModel="{Binding CasingListViewModel}" />

什么都没发生。具体来说,永远不会调用setter,并且该属性保持为null。我知道源属性CasingListViewModel有一个值,因为我试图将它绑定到另一个属性(DataContext),并且它工作正常。

我认为依赖属性可以是数据绑定。我错了吗?

1 个答案:

答案 0 :(得分:6)

有时会发生问题,结果却不是我们想象的那样。

我提到从未调用过setter。那是真实的。上面的代码略微修剪,以使其更清晰。不幸的是,在调用SetValue之后,我还在setter中删除了一个语句。该语句将值赋给DataContext,如下所示:

public ViewModelBase ViewModel
{
    get { return GetValue(ViewModelProperty) as ViewModelBase; }
    set
    {
        SetValue(ViewModelProperty, value);
        DataContext = value;
    }
}

正如我现在从this excellent article学到的,当通过数据绑定设置属性时,实际上 setter被绕过。该框架反而直接针对DependencyObject。所以该属性实际上是设置的,但是setter从未被调用过(正如我所提到的),结果是DataContext保持为null并且没有任何效果。

所以:首先,我为提出一个无法回答的问题而道歉。其次,作为弥补它的一种方式,我可以传递非常重要的建议:

  

永远不要将GetValue()和SetValue()放在属性getter / setter中,因为它们并不总是被调用!

编辑:稍后,我还发现了这种方法的另一个问题。通过这种方式设置DataContext,我实际上首先丢失了支持绑定的原始数据上下文。结果是该属性立即重置为null。总而言之,总的来说这不是一个好方法。