我不确定这是4.0中的错误还是对DP和绑定(bind)的误解。
*注意:这适用于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事件中执行此操作有关?

但是,也许我错过了一些东西,所以这就是为什么我在这里问:)

更新

Even per Microsoft:



并且,根据反射:
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,发现至少在SourceItemSetBinding确实得到了正确的评估。我将查看是否有一种方法可以让我跟踪此情况,以查看它是否/何时更改。

更新#3

经过进一步调试后,我发现更改后的事件仅发生在SetBinding上。如果我将DefaultEnumValue设置为SetBinding发生时的状态,则更改根本不会触发

更新#4

如果我调用this.SetValue(MyDP, SomeEnumVal); *,则可以正常工作,甚至可以写入VM。我尝试更改DP,以便将元数据设置为默认的双向绑定(bind),以查看是否有帮助,但没有

*这并不令我感到惊讶,因为SetBinding本身会执行target.SetValue(dp, bindingExpressionBase);,这说明了为什么它能工作一次。

最佳答案

这当然看起来很奇怪,但是我认为这里发生的事情与绑定(bind)的来源无关,而是与您如何设置路径有关。您的第一种情况称为SetBinding(DependencyProperty, string),后者又称为SetBinding(DependencyProperty, new Binding(path))Binding构造函数在内部将Path设置为new PropertyPath(path, new object[0])-无参数的路径。

在第二种情况下,您将创建自己的PropertyPath,但要通过另一个构造函数,该构造函数接受object类型的单个参数,该参数表示一个参数。该构造函数似乎将Path设置为"(0)"并将您的"MyProp"字符串设置为绑定(bind)的参数。

这是MSDN关于该构造函数的内容:



我仍然不确定为什么第一种情况不起作用,但是可以想象一下,由于某种原因,因为该参数不必是依赖项属性,而可以是常规CLR属性,因此将其视为后者。

在第二种情况下,该属性被解释为“ Storyboard 目标的单步路径”(即使我想可能不是),但是由于在此用法中它必须是依赖项属性,因此绑定(bind)对它的处理方式有所不同。

为了保持一致性,您可以在第二种情况下尝试将Path设置为:

Path = new PropertyPath("MyProp", new object[0])

当然,现在我希望您的绑定(bind)在两种情况下都只能工作一次!它可能会恢复一些理智,但也可能表明绑定(bind)问题在其他地方。

关于c# - 使用字符串路径的SetBinding仅在.NET 4.0中的SetBinding上触发更改事件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15797691/

10-10 13:45