Question

I have bound an ASP.net GridView to a collection of anonymous types.

How can I reference one of the properties of the anonymous types in the RowDataBound event handler?

I am already aware of the way to cast the anonymous type like this:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        var AnonObj = Cast(e.Row.DataItem, 
          new { StringProperty = "", BoolProperty = false, IntProperty = 0 });

        if (AnonObj.BoolProperty)
        {
            e.Row.Style.Add(HtmlTextWriterStyle.Color, "Red");
        }
    }
}


T Cast<T>(object obj, T type)
{
    return (T)obj;
}

I think most would say this is messy, even though it does work. In my real code, I have more than 3 properties and I would have to update code in two places anytime I added or reordered the properties of my anonymous type.

Is there a better way to tell e.Row.DataItem that it has a specific property of a specific type and force the object to give me that value (besides creating a class)?

Was it helpful?

Solution

The way you are using (cast by example) is messy and very brittle - I really don't recommend it (if you add a property, or name them in a different order, it'll break; etc). The better approach is to use your own named type in the projection.

OTHER TIPS

Look into using reflection.

Example:

object o = e.Row.DataItem;
Type t = o.GetType();
PropertyInfo pi = t.GetProperty("StringProperty");
if (pi != null && pi.PropertyType == typeof(string))
{
  // the property exists!
  string s = pi.GetValue(o, null) as string;
  // we have the value
  // insert your code here
  // PROFIT!  :)
}

Error-checking and optimization left as an exercise to the reader.

A better way would be to create a type to handle this so you don't have to do all that casting to use the anonymous type.

What I do is ... for example,

string Name = (string)DataBinder.Eval(dataItem.DataItem, "Name");

... but this is in a listview ItemDataBound event handler. Thought it might be useful for someone.

No, I don't believe there's any better way than this. The C# guys don't really support using anonymous types outside of local method scope (i.e. here you have an anonymous type attached to your Row object.)

The usual suggestion would be to make a real class instead.

The method you're using to cast the anonymous object (while very cool) is a hack. It works simply because the C# compiler is smart enough to only create one instance of the Anonymous Class for the entire app if the Properties are the same. So there really is no benefit in using anonymous types, since a class is being created behind the scenes anyway. Yes, you can hack it, you can use reflection, but seriosuly, why bother? What benefit is there to using Anonymous types in this case?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top