A DependencyProperty with a CoerceValueCallback is behaving weird
05:27 15 Apr 2026

I'm currently struggling with DependencyProperties in WPF. Full code can be found here: https://github.com/JYPDWhite/WPFValueCorrectionTest

In this code I have 2 problems that I can't figure out how to fix.

The code contains a OwnControl which is derived from UserControl, it contains a DependencyPropertyNumber aka NumberProperty. There is a coerceValueCallback registered that coerce the given number to 0 when the given value is >5.

public static readonly DependencyProperty NumberProperty = DependencyProperty.Register(
    nameof(Number),
    typeof(int),
    typeof(OwnControl),
    new FrameworkPropertyMetadata(
        defaultValue: 2,
        flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
        propertyChangedCallback: PropertyChangedCallback,
        coerceValueCallback: CoerceNumberValue));

private static object CoerceNumberValue(DependencyObject d, object baseValue)
{
    OwnControl depObject = (OwnControl)d;
    var newValue = (int)baseValue;
    var correctedNumber = depObject.CheckNumber(newValue);

    return correctedNumber;
}

public int Number
{
    get { return (int)GetValue(dp: NumberProperty); }
    set { SetValue(dp: NumberProperty, value); }
}

private int CheckNumber(int newValue)
{
    if (newValue < 5)
    {
        return newValue;
    }

    return 0;
}

The coerced value is correctly saved in the OwnControl, to propagate the correction back to the View Model I use this propertyChangedCallback where the Binding is updated using BindingOperations.

private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (!Equals(e.OldValue, e.NewValue))
    {
        d.SetCurrentValue(dp: NumberProperty, e.NewValue);
        d.Dispatcher.BeginInvoke(new Action(() =>
        {
            var be = BindingOperations.GetBindingExpression((OwnControl)d, dp: NumberProperty);
            if (be == null)
            {
                Debug.WriteLine("Istnull");
            }
            be?.UpdateSource();
        }), DispatcherPriority.ContextIdle);
    }
}

This seems to work just fine. If I enter 2 as input the ViewModel and the OwnControl get the correct value. Then I enter 5 the value is getting coerced and the change is reflected in OwnControl and in the ViewModel. But when I now enter for example 6 (replacing the the 0 in the input field) I see that the coercing is executed and the OwnControl get the correct value 0. But the debugger is not running through the PropertyChangedCallback and so also in the ViewModel 6 is still the stored value.

Question 1: Why is the updating of the coerced value failing when I enter a "wrong" number repeatedly?

Question 2: In the DependencyProperty.Register the defaultValue is set to 2 but upon startup I can see in the debuger when hitting Breakpoint in PropertyChangedCallback that initally the value is set to 2 but the first hit of the debugger in den PropertyChangedCallback oldValue is 2 and newValue is 0. From where is the 0 comming?

c# wpf mvvm wpf-controls dependency-properties