DataGridView绑定后新增行未同步至底层DataTable如何解决
DataGridView新录入行未同步到绑定DataTable的解决方法
问题根因
这是WinForm DataGridView数据绑定的默认机制导致的,和你调用AcceptChanges()没有关系:
- 界面上带星号的空白新增行,在编辑会话未正式结束前,录入的所有数据只会暂存在DataGridView控件层,不会自动向下推送到BindingSource,更不会写入绑定的DataTable。
DataTable.AcceptChanges()方法仅对已经进入DataTable集合的行生效,作用是提交行的状态变更,完全无法把控件层暂存的未提交编辑数据拉取到DataTable中。- 调试时看不到新行,本质是这行对应的DataRow还处于
Detached(分离)状态,不属于DataTable的Rows集合,自然不会出现在监视结果里。 - 你观察到的
CellValueChanged事件触发,仅代表单元格的值在控件层面完成了修改,不代表数据已经同步到下层数据源。
修复方法
在保存按钮的点击逻辑中,在读取DataTable数据前,按顺序执行以下代码强制结束各层级的编辑状态,即可把控件中录入的新行同步到DataTable:
// 结束DataGridView当前单元格/行的编辑,把控件内的单元格值提交到行缓存 yourDataGridView.EndEdit(); // 结束BindingSource的编辑,将缓存的新增/修改行正式推送到绑定的DataTable yourBindingSource.EndEdit();
如果你的DataTable存在于带层级约束的DataSet中,可以额外加一行yourDataTable.EndInit()确保约束校验通过,完成数据提交。执行完上述代码后,再查看DataTable的Rows集合就能看到刚录入的新行。
注意事项
- 如果你的保存按钮设置了
CausesValidation = false,点击按钮时不会触发控件失焦验证流程,永远不会自动提交编辑,必须手动调用上述两个EndEdit()方法。 - 新行同步到DataTable后,默认
RowState为Added,直接用DataAdapter的Update()方法即可完成数据库持久化,不要在调用Update之前执行AcceptChanges()——该方法会把所有行的RowState重置为Unchanged,导致DataAdapter识别不到新增/修改的行,不会生成对应的INSERT/UPDATE SQL语句。
相关操作界面参考
- 初始带星号的空白新增行状态:

- 录入第一个单元格值后自动生成新空白行状态:

- 整行内容录入完成未提交编辑状态:

- 未执行EndEdit时DataTable的调试监视结果:

- 执行EndEdit后数据同步完成的监视结果:

内容的提问来源于stack exchange,提问作者Dejan Dozet
相关产品推荐
相关产品推荐

