Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DependencyProperty ValidateValueCallback question

I added a ValidateValueCallback to a DependencyProperty called A. Now in the validate callback, A shall be compared to the value of a DependencyProperty called B. But how to access the value of B in the static ValidateValueCallback method validateValue(object value)? Thanks for any hint!

Sample code:

class ValidateTest : DependencyObject
{
    public static DependencyProperty AProperty = DependencyProperty.Register("A", typeof(double), typeof(ValidateTest), new PropertyMetadata(), validateValue);
    public static DependencyProperty BProperty = DependencyProperty.Register("B", typeof(double), typeof(ValidateTest));


    static bool validateValue(object value)
    {
        // Given value shall be greater than 0 and smaller than B - but how to access the value of B?

        return (double)value > 0 && value <= /* how to access the value of B ? */
    }
}
like image 586
stefan.at.wpf Avatar asked Jun 16 '10 16:06

stefan.at.wpf


People also ask

What is CoerceValueCallback?

The CoerceValueCallback for a dependency property is invoked any time that the property system or any other caller calls CoerceValue on a DependencyObject instance, specifying that property's identifier as the dp . Changes to the property value may have come from any possible participant in the property system.

What is dependency property?

A dependency property can reference a value through data binding. Data binding works through a specific markup extension syntax in XAML, or the Binding object in code. With data binding, determination of the final property value is deferred until run time, at which time the value is obtained from a data source.


1 Answers

Validation callbacks are used as sanity checks for the given input value against a set of static constraints. In your validation callback, checking for a positive value is a correct use of the validation, but checking against another property is not. If you need to ensure a given value is less than a dependent property, you should use property coercion, like so:

public static DependencyProperty AProperty = DependencyProperty.Register("A", typeof(double), typeof(ValidateTest), new PropertyMetadata(1.0, null, coerceValue), validateValue);
public static DependencyProperty BProperty = DependencyProperty.Register("B", typeof(double), typeof(ValidateTest), new PropertyMetaData(bChanged));

static object coerceValue(DependencyObject d, object value)
{
    var bVal = (double)d.GetValue(BProperty);

    if ((double)value > bVal)
        return bVal;

    return value;
}

static bool validateValue(object value)
{
    return (double)value > 0;
}

While this won't throw an exception if you set A > B (like the ValidationCallback does), this is actually the desired behavior. Since you don't know the order in which the properties are set, you should therefore support the properties being set in any order.

We also need to tell WPF to coerce the value of property A if the value of B changes, as the coerced value could change:

static void bChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    d.CoerceValue(AProperty);
}
like image 189
Abe Heidebrecht Avatar answered Sep 22 '22 06:09

Abe Heidebrecht