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”.