Binding to anonymous types in an Xbap or Silverlight application

It's easy to use Linq queries to create objects, and to use {Binding}s to bind properties of those objects into your view. If you're doing this for an application that will run as an Xbap ("WPF Browser Application") or as a Silverlight app, just note that you need to generate nominal types rather than anonymous types.

For example, say you have a bound ListBox like:

<ListBox Name="ListBox1">

    <ListBox.ItemTemplate>

        <DataTemplate>

            <TextBlock Text="{Binding First}" />

        </DataTemplate>

    </ListBox.ItemTemplate>

</ListBox>

... where the ListBox ItemsSource is established with the following code at initialization-time:

public partial class Window1 : Window

{

    private Collection<Person> _collection = new Collection<Person>()

    {

        new Person() { FirstName = "John", LastName = "Doe" },

        new Person() { FirstName = "Jane", LastName = "Doe" },

        new Person() { FirstName = "Fred", LastName = "Flinstone" }

    };

    public Window1()

    {

        InitializeComponent();

        ListBox1.ItemsSource = from person in _collection

                               where person.LastName == "Doe"

                               select new { First = person.FirstName, Last = person.LastName };

    }

}

This won’t show anything in the ListBox. (You might see debug output like “System.Windows.Data Error: 12 : Cannot get 'First' value (type 'String') from '' (type '<>f__AnonymousType0`2')”).

The issue here is that the select statement in the query (select new { First = person.FirstName, Last = person.LastName }) generates an internal (anonymous) type, and with an Xbap or Silverlight app you can’t bind to internal types. The solution is to use a nominal type. E.g., add this class definition:

public class SelectedPerson

{

    public string First { get; set; }

    public string Last { get; set; }

}

... and use it in the select:

ListBox1.ItemsSource = from person in _collection

                       where person.LastName == "Doe"

                       select new SelectedPerson { First = person.FirstName, Last = person.LastName };

... and your list box is populated with “John” and “Jane”.

Comments

  • Anonymous
    May 06, 2008
    PingBack from http://www.alvinashcraft.com/2008/05/06/dew-drop-may-6-2008/

  • Anonymous
    May 23, 2008
    My latest links about WPF (Apps, Controls, 3.5sp1 beta, HowTo, for LOB), Silverlight, XAML and URLs WPF

  • Anonymous
    July 17, 2009
    Good post , I didn't find the exception information in the debug outputs window. Could you like to tell me the reason . :)

  • Anonymous
    December 16, 2009
    Sorry, I'm not sure why you're not seeing the debug output.  If you run it under the debugger it should just show up.

  • Anonymous
    June 10, 2010
    In case anyone is interested in some interesting work arounds for the need for nominal types, see: grahammurray.wordpress.com/.../binding-to-anonymous-types-in-silverlight