Home > C#, WPF > XamlParseException – ‘The invocation of the constructor on type…’ – A common bug

XamlParseException – ‘The invocation of the constructor on type…’ – A common bug


There is an exception which many people hit when first creating dependency properties.

System.Windows.Markup.XamlParseException: The invocation of the constructor on type ‘[type name here]’ that matches the specified binding constraints threw an exception.

Don’t worry – it’s very easy to fix and also very commonly made.

You first dependency property may look something like this, especially if you use the code snippet “propdp“.

        public long MyProperty
        {
            get { return (long)GetValue(MyPropertyProperty); }
            set { SetValue(MyPropertyProperty, value); }
        }

        public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.Register(
                "MyProperty",
                typeof(long),
                typeof(MyClass),
                new PropertyMetadata(0));

If you created your code using the code snippet it will compile just fine and the world will be a happy place. The problem lies in the constructor of the PropertyMetadata on line 12 above where you set the default value for the property.

The definition of the constructor is:

public PropertyMetadata(object defaultValue);

The type of the parameter ‘defaultValue‘ is ‘object‘, this means that your default value will be boxed as an object type.

The error comes when the default value is needed and is unboxed. If you didn’t carefully force the type of the value going in then the most sensible type will be chosen by the compiler, which may differ from the type you specified on line 10, i.e. the underlying type you wish to use for your dependency property.

Using the above as an example, the default value is set to ‘0‘ – the compiler will interpret ‘0‘ to be an Int32 and then the constructor will store that Int32 typed value as the default value in the defaultValue object.

When you come to need the default value the code that is executed behind the scenes will attempt to turn your default value back to the type specified for your dependency property, i.e.

long value = (long)defaultValue;

Much to many people’s surprise, this is not possible and will throw the exception above. Why? Well, you need to unbox back to the underlying type before you cast it to another type.

Take the following code, which you can paste into a console project to check out:

var myInt = 0;
Console.WriteLine(myInt.GetType().Name); // produces Int32

object myObj = myInt;
Console.WriteLine(myObj.GetType().Name); // produces Int32 - the underlying type

// no problem
long myLong1 = (long)myInt;

// no problem - unboxing to int and then casting to long
long myLong2 = (long)(int)myObj;

// exception - can't unbox to a different type
long myLong3 = (long)myObj;

Note that on line 1 I declared the variable using var instead of int, however we can still see that the compiler has decided that Int32 is the best way to go with this value.

So, back to the exception, and how to correct it. Simple really, make sure that the compiler is aware of the type of value that you are passing in and make sure that it matches the type you are declaring for your dependency property.

In the example above we only need to replace line 12 with the following using an explicit cast.

                new PropertyMetadata((long)0));

Alternatively we could have used a type suffixes as a shortcut.

 new PropertyMetadata(0l));

Other type suffices are:
u – uint
l – long
ul – ulong
f – float
d – double
m – decimal

If you are interested in a more depth article on boxing and unboxing and casting in general, see Eric Lippert’s excellent blog post.

Advertisements
  1. July 29, 2011 at 1:59 pm

    Interesting stuff, Steve, thanks for sharing.

  2. Cameron
    December 30, 2011 at 4:38 pm

    Thanks! That fixed the issue for me.

  3. Mark P
    February 15, 2012 at 5:09 pm

    Good work Steve. Helped to get to the bottom of somebody else’s control that got handed over to me. It gave same error as above and pointed me in the right direction.

    • Steven Wilber
      February 17, 2012 at 8:40 am

      Glad I could be of assistance. Funny the way the world works isn’t it.

  4. James S
    May 10, 2012 at 6:04 pm

    This was an extremely helpful post… saved me from myself. Thanks!

  5. Paul H
    June 1, 2012 at 5:46 am

    Thanks for the post saved me from tearing my hair out 🙂

  6. DP
    August 22, 2012 at 9:19 am

    Dude, I was losing my sanity. Thanks a lot!

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: