5

我正在开发一个显示绑定到某个数据库表的 DataGridView 的 Winforms 应用程序。

它允许在其中插入新条目,并进行一些数据验证。

当必填列留空或违反其中一个唯一约束时,DataError 事件将调用此函数:

protected void _data_error(object sender, DataGridViewDataErrorEventArgs e)
{
    MessageBox.Show(this,e.Exception.Message,"Error");
    e.ThrowException = false;
    e.Cancel = false;
}

当弹出窗口关闭时,正在编辑的新行将被删除。
当对已保存的行(更新操作)执行此操作时,该行将丢失其更改并失去焦点。我认为这意味着我需要向应用程序发出信号以保持行可编辑,但我不知道该怎么做。

矛盾的是,如果我用一个异常替换事件处理程序,throw(e.Exception)异常就会被抛到风中并被未捕获的异常处理程序拾取,但在该窗口关闭后新行被保留。

如何在 DataError 事件中保留新行?

编辑:

我的下一个想法是保存该行并在 MessageBox 弹出后将其添加到 DataGridView 的数据源中。这不起作用,因为将数据添加到数据源会将其添加为已提交的行,这会因为无效数据而引发异常,而不是将数据保留为可编辑行,这样就不会发生验证。

4

2 回答 2

8

花了我几天时间,但这是我修复它的方法,但我仍然愿意寻求更好的方法。

DataGridView.RowValidating事件中,验证每个单元格的内容。如果无效,请执行以下操作:

Grid.Rows[e.RowIndex].ErrorText = "Concisely describe the error and how to fix it";
e.Cancel = true;

并确保在下一次通过事件处理程序时清除错误文本。

对于用户输入无效数据类型的情况,例如将文本输入到仅限数字的列中,您必须在DataGridView.DataError事件中处理错误。使用相同的代码:

Grid.Rows[e.RowIndex].ErrorText...

但无需清除 ErrorText,因为您的行验证事件会处理它。

注意:这不会让您有弹出窗口来通知用户出了什么问题,它将使用 DataGridView 错误,这是网格左侧的红色感叹号,鼠标悬停文本显示您填写的 ErrorText。每当您有MessageBox弹出窗口时,它就会出现,您将失去对可编辑数据的关注并丢失该行。

于 2012-11-26T21:11:51.240 回答
4

来自 MSDN

private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs anError)
{
MessageBox.Show(anError.RowIndex + " " + anError.ColumnIndex);
MessageBox.Show("Error happened " + anError.Context.ToString());

if (anError.Context == DataGridViewDataErrorContexts.Commit)
{
    MessageBox.Show("Commit error");
}
if (anError.Context == DataGridViewDataErrorContexts.CurrentCellChange)
{
    MessageBox.Show("Cell change");
}
if (anError.Context == DataGridViewDataErrorContexts.Parsing)
{
    MessageBox.Show("parsing error");
}
if (anError.Context == DataGridViewDataErrorContexts.LeaveControl)
{
    MessageBox.Show("leave control error");
}

if ((anError.Exception) is ConstraintException)
{
    DataGridView view = (DataGridView)sender;
    view.Rows[anError.RowIndex].ErrorText = "an error";
    view.Rows[anError.RowIndex].Cells[anError.ColumnIndex].ErrorText = "an error";

    anError.ThrowException = false;
}
}
于 2014-04-01T09:45:34.320 回答