How to change datagridview column date format when gridview has autogeneratecolumns=true

元气小坏坏 提交于 2019-12-04 09:57:46

Disclaimer: I haven't tried this myself, but it looks possible.

A GridView has a public property called ColumnsGenerator that has a type of IAutoFieldGenerator. This is the object that determines how the columns are generated.

There's already an implementation of IAutoFieldGenerator out there, the default one: GridViewColumnsGenerator. This is a public, non-sealed class, and you can derive a type from it.

The method you would have to override is this one:

public override List<AutoGeneratedField> CreateAutoGeneratedFields(
      object dataObject, Control control);

Note the output, a List<T> of AutoGeneratedField. AutoGeneratedField has a property called DataFormatString:

public override string DataFormatString { get; set; }

So all you'd have to do is override CreateAutoGeneratedFields, like this:

public class MyDerivedGridViewColumnsGenerator : GridViewColumnsGenerator
{
   public override List<AutoGeneratedField> CreateAutoGeneratedFields(
      object dataObject, Control control)
   {
       var list = base.CreatedAutoGeneratedFields(dataObject, control);
       foreach(var field in list)
       {
         if(field.DataType == typeof(DateTime))
             field.DataFormatString = "dd-MMM-yyyy";
       }
       return list;
   }
}

Now, I'm not clear on how the ColumnsGenerator property gets set, so you might have to do it in code. But that should be fairly simple, since GridViewColumnsGenerator has a parameterless constructor:

 // GridView myGridView;
 myGridView.ColumnsGenerator = new MyDerivedGridViewColumnsGenerator();

I would set it before you bind to the GridView, so it's in place when it's time to create the columns.

I'm a little late. But this worked for me. It still uses the RowDataBound() method. But it only runs against the first row in the data source.

        protected void gvGridView_RowDataBound(Object sender, GridViewRowEventArgs e)
        {
            DataRowView drv = (DataRowView)e.Row.DataItem;

            if (e.Row.RowType == DataControlRowType.DataRow)
            {

                for (int i = 0; i < ct_columns; i++)
                {
                    DataControlFieldCell dcf = e.Row.Cells[i] as DataControlFieldCell;

                    /* default date format: hide 'time' values */
                    if (e.Row.RowIndex == 0 
                        && (dcf.ContainingField.GetType().Name == "BoundField"           // defined columns
                        || dcf.ContainingField.GetType().Name == "AutoGeneratedField"))  // auto-generated columns 
                    {
                        BoundField bf = dcf.ContainingField as BoundField;

                        if (bf != null && String.IsNullOrEmpty(bf.DataFormatString))
                        {
                            string col_name = bf.DataField;

                            if (!String.IsNullOrEmpty(col_name) && drv[col_name] != null)
                            {
                                if (drv[col_name].GetType().Name == "DateTime")
                                {
                                    // set format for first row
                                    string date = drv[col_name].ToString();
                                    if (!String.IsNullOrEmpty(date))
                                        dcf.Text = DateTime.Parse(date).ToShortDateString();

                                    // set format for other rows
                                    bf.DataFormatString = "{0:M/dd/yyyy}";  
                                }

                            }
                        }
                    }
                }
            }
        }
Gowtham.K.Reddy

if you are binding an DataTable to Grid then Write an extension method or link Query like

public static void ChangeDateFormat<T>(this DataColumn column, Func<object, T> conversion)
{
   foreach(DataRow row in column.Table.Rows)
   {
    row[column] = conversion(row[column]);
   }
}

And to call that Method

dataTable.Columns["DateColumanName"].ChangeDateFormat(
val => DateTime.Parse(val.ToString()).ToString("dd/MMM/yyyy"));

Actual Source code pulled from here
And also note you need check the existence of column and data type and the other checks to get rid of errors.

Hope it helps.

Here's a fairly simple solution: rather than handle each row separately, set-up the columns before binding the grid.

In the following example, view is an object that generates a regular DataTable and the grid view has its AutoGenerateColumns property set to false.

Essentially, you just examine the columns' data type and when its a DateTime, set the format you want.

DataTable dt = view.GetReport();

Type dateType = typeof(DateTime);
foreach (DataColumn column in dt.Columns)
{
    BoundField f =  new BoundField();
    f.HeaderText = column.ColumnName;
    f.DataField = column.ColumnName;

    if(column.DataType == dateType)
        f.DataFormatString = "{0:d}"; // Or whatever

    gvReport.Columns.Add(f);
}

gvReport.DataSource = dt;
gvReport.DataBind();

I managed to format the values of an auto generated datetime column implementing the event ColumnAdded of the DataGridView:

    private void dataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
    {
        if (e.Column.ValueType == typeof(DateTime))
        {
            e.Column.DefaultCellStyle.Format = "dd-MMM-yyyy";
        }
    }

Use Eval function to define string formation in aspx code:

<% # Eval("Date", "{0:dd-MMM-yyyy}") %>

Complete Example:

<asp:TemplateField HeaderText="Date">
    <ItemTemplate>
        <% # Eval("Date", "{0:dd-MMM-yyyy}") %>
    </ItemTemplate>
</asp:TemplateField>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!