DataTable与DataGridView的奇怪行为

4
请帮我解释一下正在发生的事情。我创建了一个WinForms .NET应用程序,该应用程序在表单上具有DataGridView,并且应该在使用DataGridView内联编辑时更新数据库。
表单具有绑定到其上的四个SqlCommand的SqlDataAdapter _da。DataGridView直接绑定到DataTable _names。
以下是CellValueChanged处理程序:
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    _da.Update(_names);
}

虽然_names DataTable已更新,但它不会更新数据库状态。所有行的 RowState 都等于 DataRowState.Unchanged。

好的,我修改了处理程序:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    DataRow row = _names.Rows[e.RowIndex];
    row.BeginEdit();
    row.EndEdit();
    _da.Update(_names);
}

这个变量确实将修改的单元格写入数据库,但当我尝试在网格中插入新行时,会出现有关索引为e.RowIndex的行不存在的错误。

因此,我决定进一步改进处理程序:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (_names.Rows.Count<e.RowIndex)
    {
        DataRow row = _names.Rows[e.RowIndex];
        row.BeginEdit();
        row.EndEdit();
    }
    else
    {
        DataRow row = _names.NewRow();
        row["NameText"] = dataGridView1["NameText", e.RowIndex].Value;
        _names.Rows.Add(row);
    }
    _da.Update(_names);
}

现在当我向网格插入新行时,真正奇怪的事情发生了:网格保持不变,直到_names.Rows.Add(row);这一行。在此之后,将插入三行到表中 - 两行具有相同的值,一行具有Null值。

稍作修改的代码:

DataRow row = _names.NewRow();
row["NameText"] = "--------------"
_names.Rows.Add(row);

插入三行,每行有不同的值:第一行与网格中输入的值相同,第二行为“--------------”值,第三行为Null值。

我真的被猜测发生了什么事情所困扰。


我不确定我是否完全复制了你的问题,但我有一个工作示例,在这个示例中,当单元格的值更改时,我可以提交到数据库,这应该是你的目标。现在发布代码,如果它对你不起作用,请留言评论。 - David Hall
3个回答

2

我有一个解决方案,但让我先解释一下发生了什么。当CellValueChanged事件被触发时,DataGridView已经识别出您对单元格进行了更改,并且实际上已经将值推送到表中,但是表仍处于编辑模式,因此修改行的RowState仍然未更改。此外,插入的行甚至在表中都不可见。要强制表反映这些更改,请调用窗体的BindingContext的EndCurrentEdit()方法:

this.BindingContext[_names].EndCurrentEdit();

或者使用DataGridView的另一个事件会更好? - Paul

1
最简单的获得您想要的行为(我认为)的方法是引入绑定源 - 将数据表设置为该绑定源的数据源,然后将绑定源设置为网格。
单元格值更改后变为:
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    bs.EndEdit();
    _da.Update(_names);
}

0

死灵回答:最简单的方法是使用另一个数据集来存储变化:

private void UpdateDB()
{
    using (SqlConnection conn = new SqlConnection(SQLString.ConnStr))   // All new connection
    {
        try
        {
            dataAdapter.SelectCommand = new SqlCommand(SQLString.QryStr, conn);
            cmd.DataAdapter = dataAdapter;

            changeSet = dataSet.GetChanges();
            if (changeSet != null)
            {
                dataAdapter.Update(changeSet, "tstRegion");
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
    }
}

请注意,原始数据集中的更改是所有更改数据集中的内容。

很遗憾,我已经很久没有使用.NET了,因此无法检查你的答案。 - Paul

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