使用DataGridView的DataTable的奇怪行为

时间:2012-11-24 22:05:34

标签: c# datagridview datatable sqldataadapter

请解释我发生了什么。我创建了一个WinForms .NET应用程序,它在表单上有DataGridView,并且在使用DataGridView内联编辑时应该更新数据库。

表单有 SqlDataAdapter _da,并绑定了四个SqlCommands。 DataGridView直接绑定到DataTable _names。

这样的CellValueChanged处理程序:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    _da.Update(_names);
}
尽管_names DataTable已更新,但

不会更新数据库状态。 _names的所有行都有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值。

我真的很难猜测发生了什么。

3 个答案:

答案 0 :(得分:2)

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

this.BindingContext[_names].EndCurrentEdit();

答案 1 :(得分:1)

获取行为(我认为)的最简单方法是引入绑定源 - 将数据表设置为绑定源的数据源,然后将绑定源设置为网格。

单元格值已更改,然后变为:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    bs.EndEdit();
    _da.Update(_names);
}

答案 2 :(得分:0)

NECRO ANSWER:最简单的方法是使用另一个数据集进行更改:

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());
        }
    }
}

请注意,原始数据集的更改都是更改数据集中的更改。