DataTable.GetChanges() 返回 null
Posted
技术标签:
【中文标题】DataTable.GetChanges() 返回 null【英文标题】:DataTable.GetChanges() returns null 【发布时间】:2014-07-31 16:25:24 【问题描述】:我有一个具有 DataGridViewCheckBoxColumn 的 DataGridView。我试图让 DataSource 更新,以便我可以检索 DataTable 的更改以保存到数据库中。我在这里和其他网站上阅读了几篇文章,但我还没有成功。我发现 CurrentCellDirtyStateChange 事件必须在 CellContentClick 事件之后执行,以避免必须从物理上移出 DataGridViewCheckBoxColumn Cell 以获取底层数据源以获取更改。如果我离开单元格,我将成功检索 .GetChanges()。问题是 CurrentCellDirtyStateChange 永远不会触发。我错过了什么?正确的处理程序在 .designer.cs 文件中定义。
private void saveChangesToolStripMenuItem_Click(object sender, EventArgs e)
DataTable dt = fileData.GetChanges();
if (dt == null) return;
foreach (DataRow row in dt.Rows)
if (row.Field<int>("Id") != null)
if (row.Field<bool>("Selected"))
// update
else
// delete
else
// add
fileData.AcceptChanges();
dgvColumnValues.ResetBindings();
private void dgvColumnValues_CellContentClick(object sender, DataGridViewCellEventArgs e)
if (e.ColumnIndex != dgvColumnValues.Columns["Selected"].Index) return;
dgvColumnValues.BeginEdit(true);
dgvColumnValues.CurrentCell.Value = !(bool) dgvColumnValues.CurrentCell.Value;
dgvColumnValues.NotifyCurrentCellDirty(true);
dgvColumnValues.EndEdit();
bsAcceptableColumn.EndEdit();
private void dgvColumnValues_CurrentCellDirtyStateChanged(object sender, EventArgs e)
if (dgvColumnValues.IsCurrentCellDirty)
dgvColumnValues.CommitEdit(DataGridViewDataErrorContexts.Commit);
更新:
即使只是绕过 IsCurrentCellDirty 检查并调用 dgvColumnValues.CommitEdit(DataGridViewDataErrorContexts.Commit);
.GetChanges() 仍然返回 null。
更新:
我想出了如何通过调用 dgvColumnValues.NotifyCurrentCellDirty(true);
来调用 CurrentCellDirtyStateChanged 事件处理程序,所有代码都在事件处理程序中正确执行,但是当我单击保存而不更改单元格焦点时 .GetChanges() 仍然为空。我的理解是 CurrentCellDirtyStateChanged 事件处理程序是解决这个问题的方法。现在我真的很难过。代码示例更新以反映新的变化。
【问题讨论】:
看看我对这个问题***.com/questions/22284280/…的回答是否有帮助。 这没有帮助。它所做的只是将我已经在 CellContentClick 事件处理程序中使用的 datagridview 的 .EndEdit() 移动到 CurrentCellDirtyStateChanged 事件处理程序中。 .GetChanges() 仍然为空。 【参考方案1】:好的,找到解决方案。我遇到了一个很棒的小助手方法here。博客文章对发生的事情进行了一些深入的介绍。该方法是为 DataSet 编写的,但我将其修改为 DataTable 以满足我的需要。所以完整的工作代码如下...
private void saveChangesToolStripMenuItem_Click(object sender, EventArgs e)
CommitProposedChanges((DataTable)dgvColumnValues.DataSource);
DataTable dt = ((DataTable)dgvColumnValues.DataSource).GetChanges();
if (dt == null) return;
foreach (DataRow row in dt.Rows)
if (row.Field<int>("Id") != null)
if (row.Field<bool>("Selected"))
// update
else
// delete
else
// add this row to the table
((DataTable)dgvColumnValues.DataSource).AcceptChanges();
dgvColumnValues.ResetBindings();
private void dgvColumnValues_CellContentClick(object sender, DataGridViewCellEventArgs e)
if (e.ColumnIndex != dgvColumnValues.Columns["Selected"].Index) return;
DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)((DataGridView)sender).Rows[e.RowIndex].Cells[e.ColumnIndex];
if (cell.ValueType != typeof(bool)) return;
cell.Value = !(bool)cell.Value;
dgvColumnValues.EndEdit();
protected virtual void CommitProposedChanges(DataTable dt)
if (dt == null) return;
for (int nRow = 0; nRow < dt.Rows.Count; nRow++)
if (dt.Rows[nRow].HasVersion(DataRowVersion.Proposed))
dt.Rows[nRow].EndEdit();
我仍然对为什么原始代码不起作用感到困惑。其他具有相同类型问题的海报似乎也取得了成功。如果有人可以向我解释,那就太好了。
【讨论】:
以上是关于DataTable.GetChanges() 返回 null的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试在 sequence 中调用挂起函数返回多个返回值 | 协程中调用挂起函数返回集合 )