C# 当gridview具有autogeneratecolumns=true时,如何更改datagridview列日期格式

C# 当gridview具有autogeneratecolumns=true时,如何更改datagridview列日期格式,c#,asp.net,.net,gridview,date-format,C#,Asp.net,.net,Gridview,Date Format,我在gridview中根据搜索参数自动生成列,将添加或删除的列很少 请建议我如何将gridview中整个列的日期格式设置为dd-mmm-yyyy 现在,我正在使用rowdatabound进行操作。它检查每一行,因此显示结果需要时间 这就是我在rowdatabound if (e.Row.RowType == DataControlRowType.DataRow) { System.Data.DataRowView dtview; DateTime dt;

我在gridview中根据搜索参数自动生成列,将添加或删除的列很少

请建议我如何将gridview中整个列的日期格式设置为
dd-mmm-yyyy

现在,我正在使用
rowdatabound
进行操作。它检查每一行,因此显示结果需要时间

这就是我在
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");
            }
        }
    }
if(e.Row.RowType==DataControlRowType.DataRow)
{
System.Data.DataRowView dtview;
日期时间dt;
整数计数器;
dtview=(DataRowView)e.Row.DataItem;

对于(intCounter=0;intCounter使用
Eval
函数定义aspx代码中的字符串格式:

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

完整示例:

<asp:TemplateField HeaderText="Date">
    <ItemTemplate>
        <% # Eval("Date", "{0:dd-MMM-yyyy}") %>
    </ItemTemplate>
</asp:TemplateField>

如果要将数据表绑定到网格,请编写扩展方法或链接查询,如

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

还请注意,您需要检查列和数据类型是否存在,以及其他检查以消除错误


希望有帮助。

免责声明:我自己还没有试过,但看起来可能

GridView
有一个名为
ColumnsGenerator
的公共属性,该属性的类型为
IAutoFieldGenerator
。这是确定如何生成列的对象

已经有了一个
IAutoFieldGenerator
的实现,默认的是:
GridViewColumnsGenerator
。这是一个公共的、非密封的类,您可以从中派生类型

您必须重写的方法是:

public override List<AutoGeneratedField> CreateAutoGeneratedFields(
      object dataObject, Control control);
因此,您只需重写
CreateAutoGeneratedFields
,如下所示:

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

我会在您绑定到
GridView
之前设置它,以便在创建列时将其放置到位。

我有点晚了。但这对我有效。它仍然使用RowDataBound()方法。但它只针对数据源中的第一行运行

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

                            }
                        }
                    }
                }
            }
        }
protectedvoid gvGridView\u RowDataBound(对象发送方,GridViewRowEventArgs e)
{
DataRowView drv=(DataRowView)e.Row.DataItem;
如果(e.Row.RowType==DataControlRowType.DataRow)
{
对于(int i=0;i
这里有一个相当简单的解决方案:不要单独处理每一行,而是在绑定网格之前设置列

在下面的示例中,
视图
是一个生成常规
数据表
的对象,网格视图的
AutoGenerateColumns
属性设置为
false

基本上,您只需检查列的数据类型,当它是
DateTime
时,设置所需的格式

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();

我成功地格式化了自动生成的datetime列的值,该列实现了DataGridView的event ColumnAdded:

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

您不能在从数据库本身返回数据时执行此操作。不,如果我在数据库中执行此操作,则还有一个问题,因此我不会执行此操作。如果在数据库中执行此操作,则无法在gridview中格式化日期,然后日期将不会分组。我将在gridview中自动生成列,所有这些都基于我们在表单中所做的选择。当用户不会在他们的报告中选择任何日期。有趣的想法!不幸的是,设置
DataFormatString
会抛出
NotSupportedException
,并且
自动生成字段
被密封。@PiotrNawrot一个美丽的理论被一个丑陋的事实毁掉了…感谢您研究它!如果您找到一个优雅的解决方案,请发布它!可能您是混乱的.NET版本:IAutoFieldGenerator来自3.5,而GridViewColumnsGenerator是在.NET4.5中实现的
        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}";  
                                }

                            }
                        }
                    }
                }
            }
        }
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();
    private void dataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
    {
        if (e.Column.ValueType == typeof(DateTime))
        {
            e.Column.DefaultCellStyle.Format = "dd-MMM-yyyy";
        }
    }