以编程方式向DataGridView添加新列

46

我有一个绑定到 DataTable 的 DataGridView。DataTable 是从数据库查询中填充的。表格包含一个名为 BestBefore 的列。BestBefore 是格式化为字符串的日期(SQLite 没有日期类型)。

我想通过编程向 DataGridView 添加一个名为 Status 的新列。如果 BestBefore 小于当前日期,则将 Status 值设置为 OK,否则将 Status 值设置为 NOT OK。

我非常新手 Winforms,所以非常需要一些示例代码。

更新:

我认为 DataColumn.Expression 用于进行简单的计算如将列的整数值乘以另一个值,但是我需要做什么?也就是说,计算现在和 BestBefore 列中(格式为字符串)的日期之间的差异,以确定为新状态列赋予什么值。欢迎提供示例代码。

3个回答

49

保持简单

dataGridView1.Columns.Add("newColumnName", "Column Name in Text");

添加行

dataGridView1.Rows.Add("Value for column#1"); // [,"column 2",...]

24

添加新列到 DataTable 并使用列的 Expression 属性来设置状态表达式。

这里可以找到一个很好的例子:DataColumn.Expression 属性

ADO.NET 中的 DataTable 和 DataColumn 表达式 - 计算列

更新

代码示例:

DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("colBestBefore", typeof(DateTime)));
dt.Columns.Add(new DataColumn("colStatus", typeof(string)));

dt.Columns["colStatus"].Expression = String.Format("IIF(colBestBefore < #{0}#, 'Ok','Not ok')", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

dt.Rows.Add(DateTime.Now.AddDays(-1));
dt.Rows.Add(DateTime.Now.AddDays(1));
dt.Rows.Add(DateTime.Now.AddDays(2));
dt.Rows.Add(DateTime.Now.AddDays(-2));

demoGridView.DataSource = dt;

更新 #2

dt.Columns["colStatus"].Expression = String.Format("IIF(CONVERT(colBestBefore, 'System.DateTime') < #{0}#, 'Ok','Not ok')", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

这对于简单的表达式来说还可以,但是我需要做的是什么呢?也就是说,计算现在时间和BestBefore列中格式化为字符串的日期之间的差异,以确定要给新状态列赋予什么值。如果有示例代码将不胜感激。谢谢。 - halfpint
@halfpint:我更新了我的答案,并提供了你所需的可工作示例。 - HABJAN
我的BestBefore列是一个字符串格式的日期和时间,而不是DateTime类型。这仍然可以工作吗?感谢您的反馈 - 非常感谢。 - halfpint
@halfpint:是的,请看更新#2。 - HABJAN

18

这是一个示例方法,可以通过编程方式向网格视图添加两个额外的列:

    private void AddColumnsProgrammatically()
    {
        // I created these columns at function scope but if you want to access 
        // easily from other parts of your class, just move them to class scope.
        // E.g. Declare them outside of the function...
        var col3 = new DataGridViewTextBoxColumn();
        var col4 = new DataGridViewCheckBoxColumn();

        col3.HeaderText = "Column3";
        col3.Name = "Column3";

        col4.HeaderText = "Column4";
        col4.Name = "Column4";

        dataGridView1.Columns.AddRange(new DataGridViewColumn[] {col3,col4});
    }
创建一个表单,添加网格视图控件并添加一些列是学习如何进行这种过程的好方法。(实际上,这个过程适用于任何类型的表单控件。所有实例化和初始化都将在设计师中完成。)然后查看表单的Designer.cs文件,了解构建过程的具体情况。(Visual Studio通过编程方式完成所有操作,但在表单设计器中隐藏了它。)对于这个示例,我为视图创建了两列,名称分别为Column1和Column2,并搜索Form1.Designer.cs查找Column1以查看它被引用的位置。以下信息是我收集、复制和修改以动态创建两列的内容。
// Note that this info scattered throughout the designer but can easily collected.

        System.Windows.Forms.DataGridViewTextBoxColumn Column1;
        System.Windows.Forms.DataGridViewCheckBoxColumn Column2;

        this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
        this.Column2 = new System.Windows.Forms.DataGridViewCheckBoxColumn();

        this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
        this.Column1,
        this.Column2});

        this.Column1.HeaderText = "Column1";
        this.Column1.Name = "Column1";

        this.Column2.HeaderText = "Column2";
        this.Column2.Name = "Column2";

我不仅想添加一列,我还想根据具有日期值的另一列的值来设置它的值。 - halfpint
在添加列之后,在DataBindingComplete事件中做如下操作:foreach (DataGridViewRow row in dgv.Rows) {if (row.Cells[7].Value.ToString()=="1") row.Cells[0].Value = "number one"; }(仅为示例...)。但请记住,它必须在DataBindingComplete中完成,否则它将保持为空白。 - BornToCode
1
我喜欢这个回答,因为它不需要额外定义DataTable。这是解决这个问题最干净、最简洁的答案。如果我可以给多于1个赞,我一定会这么做。非常好的回答... - barrypicker
+1 太棒了!谢谢你教我如何钓鱼。这种技巧对于学习关于WinForms的许多事情都非常有用。 - John Henckel
@JohnHenckel 没关系,这就是 Stack Overflow 的全部意义。同时,感谢您的友善反馈! - Paul Sasik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接