【问题标题】:How to change datagridview column date format when gridview has autogeneratecolumns=true当gridview具有autogeneratecolumns = true时如何更改datagridview列日期格式
【发布时间】:2014-09-18 11:36:33
【问题描述】:

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

请建议我将日期格式设置为 dd-mmm-yyyy 以用于 gridview 中的整个列。

目前,我正在使用 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");
            }
        }
    }

这会检查所有记录,然后根据条件进行更改。

但我想做得更好,只需识别列并更改完整列的日期格式。

【问题讨论】:

  • 在从数据库本身返回数据时,你不能这样做吗?
  • 不,如果我在数据库中这样做,还有一个问题,所以我不这样做。如果我在数据库中做,我不能在gridview中格式化日期,然后日期不会被分组。

标签: c# asp.net .net gridview date-format


【解决方案1】:

免责声明:我自己没有尝试过,但看起来可行。

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

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

你必须重写的方法是这个:

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

注意输出,AutoGeneratedField 的 ListAutoGeneratedField 有一个名为 DataFormatString 的属性:

public override string DataFormatString { get; set; }

所以你所要做的就是覆盖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;
   }
}

现在,我不清楚ColumnsGenerator 属性是如何设置的,因此您可能必须在代码中进行设置。但这应该相当简单,因为GridViewColumnsGenerator 有一个无参数构造函数:

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

我会在您绑定到GridView 之前设置它,因此在创建列时它就位。

【讨论】:

  • 有趣的想法!不幸的是设置DataFormatString 抛出NotSupportedExceptionAutoGeneratedField 被密封。
  • @PiotrNawrot 一个美丽的理论被一个丑陋的事实毁掉了......感谢您研究它!如果您找到一个优雅的解决方案,请发布!
  • 可能你搞砸了 .NET 版本:IAutoFieldGenerator 来自 3.5,而 GridViewColumnsGenerator 是在 .NET 4.5 中实现的
【解决方案2】:

我来晚了。但这对我有用。它仍然使用 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}";  
                                }

                            }
                        }
                    }
                }
            }
        }

【讨论】:

    【解决方案3】:

    如果您将 DataTable 绑定到 Grid,则编写扩展方法或链接查询,如

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

    然后调用那个方法

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

    Actual Source code pulled from here
    另外请注意,您需要检查列和数据类型的存在以及其他检查以消除错误。

    希望对你有帮助。

    【讨论】:

      【解决方案4】:

      这是一个相当简单的解决方案:不是单独处理每一行,而是在绑定网格之前设置列

      在以下示例中,view 是一个生成常规DataTable 的对象,并且网格视图的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();
      

      【讨论】:

        【解决方案5】:

        我设法格式化了实现 DataGridView 的事件 ColumnAdded 的自动生成的日期时间列的值:

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

        【讨论】:

        • 看起来你的答案对 DataGridView 很有效,但这是 WinForms 中的一个控件。这个问题是关于没有 ColumnAdded 事件的 ASP.NET GridView 控件。
        【解决方案6】:

        使用Eval函数在aspx代码中定义字符串格式:

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

        完整示例:

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

        【讨论】:

        • 我在 gridview 中自动生成列,所有这些都是基于我们在表单中所做的选择。当用户不会在他们的报告中选择任何日期时会发生什么。
        猜你喜欢
        • 2011-11-25
        • 2012-01-21
        • 1970-01-01
        • 2012-12-07
        • 1970-01-01
        • 2011-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多