views:

194

answers:

3

Hi,
I have a GridView what I fill through a LINQ expression.
Something like this:

GridView1.DataSource = from c in customers, o in c.Orders, 
  total = o.Total where total >= 2000 select new {id = c.CustomerID, 
  order = o.OrderID, total = total};

And in its RowCreated method I try to get a property, for example the id, but it has no a known type:

object element = e.Row.DataItem;
int id = element.id; // It's bad!!!!!!

How can I do?
Thanks!!

+2  A: 

You need to use reflection.

Type t = element.GetType();
int id = 0;

foreach (PropertyInfo p in t.GetProperties())
{
    // Not very nice but finds an integer property called "id"
    if (p.PropertyType == typeof(int) && p.Name == "id")
    {
       id = (int)p.GetValue(element, null);
    }
}

Using Linq:

Type t = element.GetType();
int id = 0;
var pt = new List<PropertyInfo>();
pt.AddRange(t.GetProperties());
id = (int)pt.Where(p => p.PropertyType == typeof(int) && p.Name == "id").First().GetValue(element, null);

Not sure it reads any better though, especially as Type.GetProperties returns an array which has to be converted to a List to get at the Linq methods.

ChrisF
+4  A: 

Name your type!

public class GridType
{
    public int Id {get; set:} . . etc
}

then in linq,

. . . select new GridType {...etc}

Then in the RowCreated method, cast the dataitem to GridType, and you can ccess it's properties.

Otherwise your looking for duck typeing which C# doesn't do.

Binary Worrier
This is the correct way to roll.
tom.dietrich
+1  A: 

This is the cost you have to pay if you want to use anonymous objects : you loose the strong typing when you leave the scope where your object is declared. I'd recommend to explicitly declare your type, unless you want to play with DataBinder.Eval...

ybo