Hi guys!
The missed binding updating after coercing a DP value was resolved only partially in my previous post. In fact the issue is still present when the binded DP type is a String!
Below my sample application screenshot downloadable here.

And, sure, here you are the new definitely fix 😉

        public string MyValue
        {
            get { return (string)GetValue(MyValueProperty); }
            set { SetValue(MyValueProperty, value); }
        }
        public static readonly DependencyProperty MyValueProperty =
            DependencyProperty.Register("MyValue", typeof(string), typeof(Window1), new UIPropertyMetadata("50", new PropertyChangedCallback(MyValueChanged), new CoerceValueCallback(MyValueCoerceValue)));

        private static void MyValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window1 w1 = d as Window1;
            w1._txtBox.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
        }

        private static object MyValueCoerceValue(DependencyObject d, object value)
        {
            string intValue = (string)value;

            if (Int32.Parse(intValue) < 0)
                intValue = "0";
            else if (Int32.Parse(intValue) > 100)
                intValue = "100";

            Window1 w1 = d as Window1;
            w1._txtBox.GetBindingExpression(TextBox.TextProperty).UpdateTarget();

            return intValue;
        }

You are may asking “why it is necessary forcing binding UpdateTarget() both in CoerceValue and PropertyChanged callbacks”?

  • UpdateTarget() in PropertyChanged: in this way we ensure that the displayed text is updated every time MyValue DP has been changed. However, what happens when the current value is “100” and the user insert “1000”? The CoerceValue sets MyValue DP to 100 but, since the old value (100) is equal to new value (100), the PropertyChanged is not called! Consequently, the TextBox still displays the last typed value (1000)!
  • UpdateTarget() in CoerceValue: in this way we cover the scenario in which the current value is “100” and the user insert a value greater than 100 (e.g. 1000).
  • Honestly, I didn’t understood the reason why in case of “int” DP property a single call of UpdateTarget() on CoerceValue is sufficient to update the displayed value.

    Happy coding!
    Marzio.

    Advertisements