Peter Wone
Peter Wone

Reputation: 18795

Adding setter behaviour to dependency properties

We are advised not to add behaviour to accessor methods of dependency property wrappers because they can be bypassed by a direct call to Get/SetValue.

OK, that's reasonable. So where do we put this behaviour?

We can supply a ValidateValueCallback delegate while registering the dependency property. This calls a static method of our provenance that takes a single parameter object value, sufficient for context independent checks like "seconds must be in the range 0-59".

Sometimes you need instance dependent context information, eg the valid range of Day depends on the instance value of Month.

What are we supposed to do in this case? This would be trivial to handle in the propdp setter.

It has been proposed below that the PropertyChanged event might be used for this kind of validation, and this is in fact what I did in the circumstance that prompted this question. However, this is ugly because at this stage the change has been committed to the model, so it is necessary to maintain an undo stack to provide access to the prior value.

There does seem to be some material in MSDN on this very topic, but I have not had time to give it the consideration it needs.

Upvotes: 1

Views: 266

Answers (1)

sa_ddam213
sa_ddam213

Reputation: 43626

I think I may have found a solution, CoerceValueCallback runs before the property is change and you can intercept and change the value if needed before its passed on any further.

Perhaps you could try this and see if it works in your situation.

public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.Register("MyProperty", typeof(int), typeof(MainWindow), new PropertyMetadata(0, null, new CoerceValueCallback(CoercePropertyValue)));

private static object CoercePropertyValue(DependencyObject d, object value)
{
    if (This != That)
    {
        return value;
    }
    return 6;
}

Upvotes: 1

Related Questions