views:

166

answers:

3

I am using a common Silverlight DataGrid to display results from a search. The "schema" of the search can vary from query to query.

To accommodate this, I am trying to dynamically populate the DataGrid. I can set explicitly set the columns, but I am having trouble setting the ItemSource. All of the MSDN examples set the ItemSource to a collection with a strong type (e.g. a Custom type with public properties matching the schema). The DataGrid then uses reflection to scour the strong type for public properties that will match the columns.

Since my search results are dynamic, I cannot create a strong type to represent what comes back. Can I not just give the DataGrid an arbitrary list of objects so long as the number of objects in each list matches the number of columns? Anyone know if this is possible?

I would like to do something similar to this:

List<List<object>> myResults = <voodoo that populates the result list>

myDataGrid.ItemsSource = myResults;
A: 

Yes, it is possible. Here is a sampel swiped from MSDN using System; using System.Collections.Generic; using System.Windows.Controls;

namespace DataGridSnippets
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            // Set the ItemsSource to autogenerate the columns.
            dataGrid1.ItemsSource = Customer.GetSampleCustomerList();
            dataGrid3.ItemsSource = Customer.GetSampleCustomerList();
            dataGrid4.ItemsSource = Customer.GetSampleCustomerList();
            dataGrid5.ItemsSource = Customer.GetSampleCustomerList();
        }
    } 

    public class Customer
    {
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public String Address { get; set; }
        public Boolean IsNew { get; set; }

        // A null value for IsSubscribed can indicate 
        // "no preference" or "no response".
        public Boolean? IsSubscribed { get; set; }

        public Customer(String firstName, String lastName, 
            String address, Boolean isNew, Boolean? isSubscribed)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Address = address;
            this.IsNew = isNew; 
            this.IsSubscribed = isSubscribed;
        }

        public static List<Customer> GetSampleCustomerList()
        {
            return new List<Customer>(new Customer[4] {
                new Customer("A.", "Zero", 
                    "12 North Third Street, Apartment 45", 
                    false, true), 
                new Customer("B.", "One", 
                    "34 West Fifth Street, Apartment 67", 
                    false, false),
                new Customer("C.", "Two", 
                    "56 East Seventh Street, Apartment 89", 
                    true, null),
                new Customer("D.", "Three", 
                    "78 South Ninth Street, Apartment 10", 
                    true, true)
            });
        }
    }
}
TheGeekYouNeed
No, this is what I stated in my question that I don't want. Customer is a strong typed class. If I don't know what fields are coming back from my search at compile time, how can I build a strongly typed class for them?
j0rd4n
A: 

The following article gets me close to what I want: http://blogs.msdn.com/b/scmorris/archive/2008/04/14/defining-silverlight-datagrid-columns-at-runtime.aspx

Essentially, you have to have a bindable property. You can't just create rows based on an arbitrary list of items. I stumbled upon a couple of open source projects that solve this problem by using reflection to build CLR types at runtime and then bind to those types.

j0rd4n
I think I'm going to redesign my project to have a strong CLR type instead of messing with the dynamic stuff. Seems much cleaner to me.
j0rd4n
A: 

Colin Eberhardt has posted an ingenious solution to the problem you've described -

http://www.scottlogic.co.uk/blog/colin/2010/03/binding-a-silverlight-3-datagrid-to-dynamic-data-via-idictionary-updated/

icysharp