How to change datagridview column date format when

2019-04-09 15:48发布

I am auto generating columns in gridview depending on search parameters, few columns will be added or removed.

Please suggest me a way to set the date format to dd-mmm-yyyy for entire column in gridview.

For now, I'm doing it using rowdatabound. It checks every row, So it takes time to show the results.

This is what I do in rowdatabound

if (e.Row.RowType == DataControlRowType.DataRow)
{
        System.Data.DataRowView dtview;
        DateTime dt;
        int intCounter;
        dtview = (DataRowView)e.Row.DataItem;

        for (intCounter = 0; intCounter <= dtview.Row.ItemArray.Length - 1; intCounter++)
        {
            if (dtview.Row.ItemArray[intCounter] is System.DateTime)
            {
                dt = (DateTime)dtview.Row.ItemArray[intCounter];
                e.Row.Cells[intCounter].Text = dt.ToString("dd-MMM-yyyy");
            }
        }
    }

This checks for all records and then changes based on condition.

But I want to do it better, just by identifying the column and change the date format for complete column.

6条回答
Viruses.
2楼-- · 2019-04-09 16:16

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>
查看更多
\"骚年 ilove
3楼-- · 2019-04-09 16:19

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();
查看更多
Rolldiameter
4楼-- · 2019-04-09 16:23

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.

查看更多
forever°为你锁心
5楼-- · 2019-04-09 16:27

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";
        }
    }
查看更多
够拽才男人
6楼-- · 2019-04-09 16:30

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}";  
                                }

                            }
                        }
                    }
                }
            }
        }
查看更多
何必那么认真
7楼-- · 2019-04-09 16:38

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.

查看更多
登录 后发表回答