4

我遇到了一个看起来很奇怪的问题,我不确定这是一个错误还是 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

4

0 回答 0