When Silverlight databinding evaluates a binding expression, it does one of two things. If the object it is bound to inherits from DependencyObject and there is a DependencyProperty matching the binding expression, it uses FrameworkElement.GetValue to retrieve the value [simplified]. If not a DependencyObject and not a DependencyProperty, Silverlight falls back to using reflection to retrieve the values.

This is problematic if you attempt to data bind to an anonymous type.

In Silverlight, when you attempt to use reflection to retrieve a property value of an internal-scoped object whose Type is not defined in your assembly, a MethodAccessExcepttion is thrown. Go ahead I’ll give you a minute to test it.

Or follow along if you want to take my word for it. Create two projects: one Silverlight Application and one Silverlight Class Library. Add a reference to the library from the application. In the library, add the following classes:

Now in the application, add the following code inside App.xaml.cs:

Run the application. The debugger will stop inside the first catch on line 8 but not the second on line 17. What this tells us is that you can use reflection to get the value of properties on a public Type defined in another assembly, but not on one that isn’t public.

Why is this important? It’s important because anonymous Types are defined internal to the assembly that they are used in. Because they are not public, and the data binding framework is not in the same assembly (it’s in System.Windows), it will receive an exception when trying to use reflection to get the value of a property from an anonymous type.

To get around this, simply create a DTO style object that is public and has all the public properties you need. Then instead of this format:

…you use this format:

…and everything works.

There are some workarounds, including giving System.Windows access to your assembly’s internals via the InternalsVisibleToAttribute and dynamically building a Type at runtime, however both seem like overkill when a simple DTO would suffice.