tags:

views:

222

answers:

4

I want to bind a List to a GridView on a web page, but override the way the property names display via annotation. I thought System.ComponentModel would work, but this doesn't seem to work. Is this only meant for Windows Forms?:

using System.ComponentModel;

namespace MyWebApp
{
    public class MyCustomClass
    {
        [DisplayName("My Column")]
        public string MyFirstProperty
        {
            get { return "value"; }
        }

    public MyCustomClass() {}
}

Then on the page:

protected void Page_Load(object sender, EventArgs e)
{
    IList<MyCustomClass> myCustomClasses = new List<MyCustomClass>
    {
        new MyCustomClass(),
        new MyCustomClass()
    };

TestGrid.DataSource = myCustomClasses;
TestGrid.DataBind();

}

This renders with "MyFirstProperty" as the column header rather than "My Column." Isn't this supposed to work?

+2  A: 

If all you care about is the header text in GridView, just use the HeaderText property of each field you bind. If you're autogenerating the columns, you just set the HeaderText after you've bound the GridView.

If you want a GridView that takes into account some attribute you placed on the properties of your bound class, I believe you'll need to create your own GridView.

I may be wrong, but I've not seen any ASP.NET Grid from control vendors (at least Telerik , Janus Systems and Infragistics) do that. If you do it, maybe sell the idea to them.

SirDemon
+2  A: 

What SirDemon said...

The answer appears to be no, you can't. At least not out of the box.

The System.Web.UI.WebControls.GridView uses reflected property's name:

protected virtual AutoGeneratedField CreateAutoGeneratedColumn(AutoGeneratedFieldProperties fieldProperties)
{
    AutoGeneratedField field = new AutoGeneratedField(fieldProperties.DataField);
    string name = fieldProperties.Name; //the name comes from a PropertyDescriptor
    ((IStateManager) field).TrackViewState();
    field.HeaderText = name; //<- here's reflected property name
    field.SortExpression = name;
    field.ReadOnly = fieldProperties.IsReadOnly;
    field.DataType = fieldProperties.Type;
    return field;
}

While System.Windows.Forms.DataGridView uses DisplayName if available:

public DataGridViewColumn[] GetCollectionOfBoundDataGridViewColumns()
{
 ...
 ArrayList list = new ArrayList();
 //props is a collection of PropertyDescriptors
 for (int i = 0; i < this.props.Count; i++)
 {
  if (...)
  {
   DataGridViewColumn dataGridViewColumnFromType = GetDataGridViewColumnFromType(this.props[i].PropertyType);
   ...
   dataGridViewColumnFromType.Name = this.props[i].Name;
   dataGridViewColumnFromType.HeaderText = !string.IsNullOrEmpty(this.props[i].DisplayName) ? this.props[i].DisplayName : this.props[i].Name;
  }
 }
 DataGridViewColumn[] array = new DataGridViewColumn[list.Count];
 list.CopyTo(array);
 return array;
}

Unfortunately, while you can override the CreateAutoGeneratedColumn, neither the missing DisplayName nor underlying property descriptor gets passed, and you can't override CreateAutoGeneratedColumns (although you could CreateColumns).

This means you'd have to iterate over reflected properties yourself and in some other place.

Ruslan
A: 

You can do it now on asp.net mvc2. It works just like that

VinTem
A: 

Are you using .net4, what you need to do is to set enabledynamicdata on the grid view to true.

cjensen