我有一个DataGridView,它有一个DataGridViewCheckBoxColumn。我试图让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事件处理程序,所有代码都在事件处理程序中正确执行,但当我单击save而不更改单元格焦点时,.GetChanges()仍为null。我的理解是CurrentCellDirtyStateChanged事件处理程序是对此的修复。现在我真的很难过。代码示例更新以反映新的更改。
答案 0 :(得分:0)
好的,找到了解决方案。我遇到了一个很棒的小助手方法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();
}
}
}
我仍然感到困惑,为什么原始代码不起作用。其他具有相同类型问题的海报似乎也取得了成功。如果有人能向我解释这将是伟大的。