When defining dependency properties in a WPF (e.g. in a user control or custom control), you can supply a default value for that property. However, if you’re not careful, you’ll get a nasty exception at runtime, with no obvious cause.
For example, consider this simple dependency property:
public double SomeLength {
get { return (double)GetValue(SomeLengthProperty); }
set { SetValue(SomeLengthProperty, value); }
}
public static readonly DependencyProperty SomeLengthProperty =
DependencyProperty.Register("SomeLength", typeof(double),
typeof(SomeControl), new UIPropertyMetadata(0));
When running the application hosting the control declaring this property, you’ll get a nasty XamlParseException. Looking at the InnerException, you’ll see something like:
{"Exception has been thrown by the target of an invocation."}
Great. Probably some reflection exception. Let’s look at its InnerException:
{"The type initializer for 'CustomControls.SomeControl' threw an exception."}
That’s a bit more helpful. It must be the DependencyProperty.Register method (called from the static constructor a.k.a. type initializer).
So, what’s going on here? Experienced WPF developers may spot this immediately. The problem is the default value of 0. What’s wrong with that? Can’t a double be zero? It can, but what’s missing is the value zero in a double look: 0.0 or (double)0.
Why is this happening? Simply because the argument Register expects is of type object. Passing a value type causes boxing. No surprise here. But when unboxing occurs – an exception is triggered, because a 0 (int) cannot be unboxed to a double without an intermediate cast (which, of course, is not supplied, as everything is too dynamic for that).
So, the moral of the story is: keep your default values with the exact type declared in the dependency property.