4

我有一个带有 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 永远不会被调用,并且该属性保持为空。我知道源属性CasingListViewModel有一个值,因为我试图将它绑定到另一个属性(DataContext),它工作正常。

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

4

1 回答 1

6

正如有时发生的那样,事实证明问题并不像我们想象的那样。

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

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

正如我现在从这篇优秀的文章中了解到的那样,当通过数据绑定设置属性时,实际上绕过了setter。相反,该框架直接针对 DependencyObject 工作。所以实际上设置了属性,但从未调用过 setter(正如我所提到的),结果是 DataContext 保持为空并且没有任何效果。

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

永远不要把 GetValue() 和 SetValue() 以外的任何东西放在属性 getter/setter 中,因为它们并不总是被调用!

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

于 2009-10-14T14:53:48.933 回答