[在ADO.NET中,我正在使用DataAdapter.Fill (..)
调用,用数据库中的值填充数据表。然后,我将DataTable绑定到DataGrid,以允许滚动浏览所有值,编辑和将更改更新回数据库。所有标准的东西。我使用了Visual Studio Windows窗体向导,因为它是如此标准。
但是现在我想显示一个左侧列(不属于数据库行)以对显示在DataGrid中的行进行编号。我仍然希望将绑定的行数据保持不变,并自动更新回数据库等等。显然,我无法使用向导进行此操作。
方法1
如果我手动进行,则将更改DataTable加载查询,以包括一个虚拟整数列,以将所需的行号列注入返回的表中:
SELECT ‘’ as Num, * from MyTable
然后,我将以编程方式将行号插入该字段,然后再将DataTable绑定到网格,网格将根据需要显示行号。我希望DataTable的自动更新代码将只忽略网格中的多余列。
方法2
[另一种可能的方法是在将新列绑定到DataSource(我的DataTable)之后,以编程方式将新列添加到DataGrid。然后在显示网格之前,用行号填充新列。
问题
但是在我放弃方便的向导并完成所有工作的手动工作之前,我想问一问是否有标准的方法来做这种事情。我不敢相信我是第一个要在网格显示中使用行号(而不是数据库行的一部分)的人。
我已经在这里和其他各种论坛中搜索了想法,但是当您将DataGrid绑定到表加载查询(方法1)或网格中时,当将新列注入表格时,它们都没有谈论更新代码会发生什么。数据源(方法2)。
我什至想到了使用两个来自不同绑定源的相邻网格控件。但是在滚动过程中保持它们同步所需的代码似乎还需要更多工作。
有人能指出我解决该问题或提供代码段的最佳方法吗?我可以进入表单设计器生成的代码来向绑定的DataGrid添加一列,但是我迷失于试图找到并了解将更改更新回数据库的更新部分。谢谢。
有一些不错的选择,它们不会干扰查询或数据结构,而只是基于GUI逻辑:
RowPostPaint
事件在RowHeader上绘制行号RowPostPaint
事件将行号分配给该行的RowPrePaint
RowPrePaint
以显示行号使用RowPostPaint事件在RowHeader上绘制行号
您可以处理HeaderCell
并在标题单元格中绘制行号。下面的代码显示了一个简单的逻辑:
HeaderCell
上面的代码足够好,但是您可能希望通过将datagridview单元格对齐方式映射到文本格式标志(例如DataGridViewRowNumberColumn
方法)来增强逻辑。您可能还希望将逻辑放入自定义RowPostPaint
中,并覆盖RowPostPaint
,并且如果派生的private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
var g = (DataGridView)sender;
var r = new Rectangle(e.RowBounds.Left, e.RowBounds.Top,
g.RowHeadersWidth, e.RowBounds.Height);
TextRenderer.DrawText(e.Graphics, $"{e.RowIndex + 1}",
g.RowHeadersDefaultCellStyle.Font, r, g.RowHeadersDefaultCellStyle.ForeColor);
}
为this,还需要设置DataGridView
属性。
使用RowPrePaint事件将行号分配给行的OnRowPostPaint
如果将字符串值分配给标题单元格的OnRowPostPaint
属性,它将显示在行标题上。
您在循环中分配值,在这种情况下,您需要处理DoubleBuffered
和DoubleBuffered
事件并重新分配行号。更好的解决方案是使用DataGridView
并检查标头单元格的值是否不正确,然后对其进行纠正:
true
创建新的HeaderCell
以显示行号
第二个选项是创建新的可重复使用的列类型以显示行号。您可以像使用其他任何列类型一样使用此列类型。您可以在设计时或运行时添加列。
Value
参见:RowAdded
– TnTinMn
TnTinMn提供了最简单的答案,可以实现我的目标。我在这里复制了他的评论,以便将其标记为已回答的问题。
一旦加载了网格,就向下走几行,并为该行左端的“页眉单元格”分配一个行标签(行号)。令人高兴的是,行号是网格中的标签,而不是网格中未绑定数据的列。