我遇到了一个看起来很奇怪的问题,我不确定这是一个错误还是 WPF 的设计特性。
我有一个具有依赖属性的依赖对象,该对象通过值强制强制执行约束,并且在与其他依赖属性的绑定中使用此属性时,一切都按预期工作。
但是,当尝试在针对 POCO 对象的绑定中使用该属性时,事情就会崩溃。在这种情况下,POCO 在依赖属性更改时更新,但在执行值强制之前,使 POCO 具有无效/不同步的值。
这是一个例子:
public class TestDO : DependencyObject
{
public static DependencyProperty NumberProperty =
DependencyProperty.Register("Number", typeof(int), typeof(TestDO),
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.None, OnNumberChanged, OnNumberCoerce));
public int Number
{
get { return (int)GetValue(NumberProperty); }
set { SetValue(NumberProperty, value); }
}
private static void OnNumberChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("DepObj: NumberChanged {0} --> {1}", e.OldValue, e.NewValue);
}
private static object OnNumberCoerce(DependencyObject d, object value)
{
int cval = (int)value;
if (cval > 10)
cval = 10;
else if (cval < -10)
cval = 10;
Console.WriteLine("DepObj: OnNumberCoerce: {0} --> {1}", value, cval);
return cval;
}
}
public class TestPOCO
{
private int _pocoNumber = 0;
public int PocoNumber
{
get { return _pocoNumber; }
set { _pocoNumber = value; }
}
}
现在,我们可以创建上述类型的两个实例以及一个绑定和测试设置 Number 属性。绑定更新 POCO 对象,但它在值强制之前这样做。
// create a POCO object
var testPoco = new TestPOCO();
// create a dependency object
var testObj = new TestDO();
// create a binding between the NumberProperty of the Dependency Object and the
// PocoNumber of the POCO object
BindingOperations.SetBinding(testObj, TestDO.NumberProperty, new Binding("PocoNumber")
{
Source = testPoco,
Mode = BindingMode.TwoWay
});
// try setting a value of 100, to trigger value coercion
testObj.Number = 100;
Console.WriteLine("Poco Number = {0}", testPoco.PocoNumber); // displays 100
Console.WriteLine("DP Number = {0}", testObj.Number); // displays 10
如果绑定存在于两个 DependencyObject 之间,则情况并非如此。在这种情况下,一切都按预期工作。SetValue --> ValueCoercion --> PropertyChanged --> SetValue