为什么 DGV 在从 DataSource 中删除项目时会导致未捕获的异常?

Why does DGV cause uncaught exception when removing item from DataSource?

我有一个带有 DataGridView 的 WinForms 应用程序,其 DataSource 属性 设置为 BindingSource(而后者又将 its DataSource 设置为 BindingList)。

一切正常,直到我响应用户请求从 BindingSource 中删除项目,我为此使用的代码是:

try
{
    // Get the item currently selected by the DGV
    var fc = (FooType)FooBindingSource.Current;
    // Remove the item from the binding source
    FooBindingSource.Remove(fch);
}
catch (Exception fault)
{
    MessageBox.Show(fault.Message);
}

Remove() 导致异常。然而,似乎并没有直接在这段代码的执行行中引发,因为这里的 cathc 没有捕获到异常。相反,当我 运行 应用程序并测试此功能时,我多次看到 DGV 默认错误对话框。令人惊讶的是,最终结果仍然是该项目确实被正确删除了!

我可以通过 un-binding 来自 DGV 的 BindingSource 在 Remove() 之前解决这个问题(使用 FooDataGridView.DataSource = null),然后重新绑定它。但这感觉......很老套,就像我只是在回避问题而不是解决问题一样,因为我不明白导致问题的原因。

我相信在删除项目时发生了某些事件,例如正在验证网格或其他内容。

这是什么原因造成的,是否有更好的方法来防止异常?

我看到的错误对话框包含以下信息,全部标题为"DataGridView Default Error Dialog"

第一个:

The following exception occurred in the DataGridView:

System.IndexOutOfRangeException: Index 413 does not have a value.

at System.Windows.Forms.CurrencyManager.get_Item(Int32 index)

at System.Windows.Forms.DataGridView.DataGridViewDataConnection.GetError(Int32 rowIndex)

To replace this default dialog please handle the DataError event.

第二个:

The following exception occurred in the DataGridView:

System.IndexOutOfRangeException: Index 413 does not have a value.

at System.Windows.Forms.CurrencyManager.get_Item(Int32 index)

at System.Windows.Forms.DataGridView.DataGridViewDataConnection.GetError(Int32 boundColumnIndex, Int32 columnIndex, Int32 rowIndex)

To replace this default dialog please handle the DataError event.

第三名:

The following exception occurred in the DataGridView:

System.IndexOutOfRangeException: Index 413 does not have a value.

at System.Windows.Forms.CurrencyManager.get_Item(Int32 index)

at System.Windows.Forms.DataGridView.DataGridViewDataConnection.GetError(Int32 rowIndex)

To replace this default dialog please handle the DataError event.

P.s:只是编写了一个快速的 DataError 事件处理程序就知道要对此进行更多研究,但我认为我会在这里抢先一步。

查看 DGV DataError 事件,我可以看到所有三个事件的事件参数上下文 属性 都设置为 "Display"。 MSDN 记录了 display as

的含义

A data error occurred when displaying a cell that was populated by a data source. This value indicates that the value from the data source cannot be displayed by the cell, or a mapping that translates the value from the data source to the cell is missing.

因此我认为这可能与 DGV 在删除过程中更新自身时试图保留删除的行 selected 有关。看到我有其他 TextBox 控件也基于 selection 显示相同的数据,那么这看起来像是一种可能棘手的循环验证事件堆栈......

为了对此进行测试,我尝试在删除该项目之前立即以编程方式将 selected 行更改为其他内容 - 成功了!我可以使用这种方法,但是当用户删除最后一项时,代码 select 应该放在哪一行?更多的荆棘和意大利面条......所以至少对可能发生的事情有一点了解我现在可以使用我提到的解除绑定和重新绑定方法。