我不确定这是否是4.0
我对 DP 和绑定的错误或误解。*注意:这适用于 3.5 和 4.5...只是不适用于 4.0
考虑以下代码:
虚拟机:
public MyEnum MyProp
{
get{return _myProp;}
set
{
_myProp = value;
OnPropertyChanged("MyProp");
}
}
查看(依赖属性设置):
MyDP= DependencyProperty.Register("MyProp", typeof(MyEnum), typeof(MyControl), new PropertyMetadata(DefaultEnumVal, MyPropChanged));
查看(在 datacontextchanged 事件中):
第一个选项
this.SetBinding(MyDP, "MyProp"); //Only triggers MyPropChanged once
第二种选择
this.SetBinding(MyDP,
new Binding
{
Source=this.DataContext,
Path = new PropertyPath("MyProp")
}
); //Works as expected
那么,考虑到所有这些,为什么第一个选项只触发一次属性更改,而更详细的方法在第一次更改之后继续?我认为第一个/字符串版本固有地使用this.DataContext
? 如果我安装.NET 4.5
,那么这对两者都按预期工作,这让我相信这是一个 4.0 错误,可能与在DataContextChanged
事件中这样做有关?
但是,也许我错过了一些东西,所以这就是我在这里问的原因:)
更新
默认情况下,绑定继承由 DataContext 属性指定的数据上下文(如果已设置)
而且,根据反射:
public BindingExpression SetBinding(DependencyProperty dp, string path)
{
return (BindingExpression)this.SetBinding(dp, new Binding(path));
}
所以,这一切都是调用与上面相同的代码,只是没有设置源。这应该会导致更新对DataContext
如果我将第二个选项保留Source
null
在第二个选项中,我可以重现第一个选项
更新#2
显然在 4.5 中,他们添加了一个ResolvedSource
属性。这表明在 4.5 中,源解析为我所期望的。我将其追溯到ClrWorker
并发现SourceItem
确实被正确评估了……至少在SetBinding
. 我将看看是否有办法让我跟踪它以查看它是否/何时发生变化。
更新#3
经过进一步调试,我发现更改的事件只发生在SetBinding
. 如果我将 设置为DefaultEnumValue
发生时的状态SetBinding
,则根本不会触发更改
更新#4
如果我调用this.SetValue(MyDP, SomeEnumVal);
* 那么这可以工作,甚至可以写入 VM。我尝试更改 DP,以便将元数据设置为 twowaybindingbydefault 以查看是否有帮助,但它没有
*这并不让我感到惊讶,因为 SetBinding 本身做了 a target.SetValue(dp, bindingExpressionBase);
,这解释了为什么它一次可以工作。