1

我不明白为什么会发生这种情况。我有一个 DataGridView,其 DataSource 设置为 BindingSource(用于过滤和导航目的)。

myDataGridView.DataSource = myBindingSource;

我有一个项目列表,单击 1 个项目将为 myBindingSource 应用相应的过滤器,结果仅显示符合 myDataGridView 标准的行。像这样:

private void ItemsClicked(object sender, ItemClickedEventArgs e){
     myBindingSource.Filter = e.FilterExpression;
}

当我单击使 myDataGridView 显示至少 1 行的项目时,这可以正常工作。但是,当我单击任何导致 0 行满足相应过滤器表达式的项目时,事情变得很糟糕。myDataGridView 通常应该是空的,但是它在某些对话框中抛出了很多异常(因此出现)(异常未在代码编辑器窗口中以黄色标记显示),这是错误对话框的快照:

在此处输入图像描述

单击“确定”按钮后,它仍然向我显示另一个(相同的)对话框,.... 它继续显示许多对话框(具有相同的消息),直到它全部停止。我不明白那是什么。我不知道您是否需要更多信息,但我希望您遇到过类似的异常,并就如何解决此问题给我一些建议。对话框说 DataError 事件,但我不明白为什么这里有任何错误?请注意,如果在应用过滤器后我的 dataGridView 中至少有 1 行,则所有过滤器都会正常,只有在过滤器后没有行时才会发生错误。

请帮帮我,非常感谢您提前!

4

2 回答 2

3

这是我的答案,我不太明白这一点,但我刚刚尝试过,它就像一个魅力。

我的规则是:

  1. SuspendBinding()在应用过滤器之前,只需使用以下方法暂停绑定来自 BindingSource 的所有控件:

    myBindingSource.SuspendBinding();

  2. 现在,只需像这样正常应用过滤器:

    myBindingSource.Filter = "filter expression";

  3. 最后,使用ResumeBinding()方法将所有控件重新绑定到 BindingSource,如下所示:

    myBindingSource.ResumeBinding();

就这样。事实上,myBindingSource 有许多绑定到它的控件。也许是这个原因,但我还是不太明白。我敢打赌,如果 myBindingSource 只有将数据绑定到的 myDataGridView,则不需要上述所有 3 个步骤,只需在需要时应用过滤器(第 2 步)即可。

我希望这可以帮助其他已经遇到,正在遇到并将遇到这个问题的人。同样,我真的不明白它为什么会起作用,所以我希望有人可以在评论中解释它。我真的很感激。谢谢!

更新

我发现在某些情况下,按照我上面描述的操作可能会出现另一个问题,最安全的解决方案是:

  1. SuspendBinding(如上所述,这是使用BindingSource 的方法SuspendBinding() 方法完成的),但最安全的方法是将您的DataSource 设置为null。

  2. 应用过滤器。

  3. ResumeBinding(如上面的描述,这是使用BindingSource的ResumeBinding()方法完成的),但最安全的方法是自己重新绑定你的控件(循环遍历每个控件并调用DataBindings的Add方法,记得先清除DataBindings)。你应该有一个方法来做这件事,因为我们可能会多次调用 re-bind 方法。

现在我正在使用这种更安全的方式,我之前提到的方式给了我另一个名为“VersionNotFoundException”的异常(没有建议的数据要访问)。异常发生在 ResumeBinding() 调用的行,该方法中必须存在一些错误。但是,我使用的是多表数据集,并在同一个 dataGridView 上的表之间切换。同样,这个问题仍然太复杂,无法立即深入理解。

真相

我发现没有必要在应用过滤器之前暂停绑定所有控件并在此之后恢复绑定。我的表单有一个控件,它绑定到 BindingSource 的一个特殊列(我们称之为 X 列),我仍然不知道为什么这个列是特殊的,我只是怀疑它并在应用之前暂停从 BindingSource 绑定它过滤并在此之后再次绑定它。不涉及所有其他控件/列。

我认为这里唯一值得注意的是:

=> 我的主表(表 1)有一个名为 A 的主键列,该表有一个名为 B 的外键,它引用另一个表(表 2)中的主键列。表 2 有一个外键,它引用另一个表(表 3)的称为 C 的主键列。事实上,我有一个查询选择了所有列 A、B、C(当然还有其他的这里没有提到)。这种关系是我所怀疑的,但我仍然不清楚它为什么以及如何引发错误。如果不使用绑定并手动分配/更新所有值,则不会出现任何错误。绑定有时非常复杂。

于 2013-04-27T01:36:04.253 回答
1

因为没有什么要过滤的,这就是为什么你得到那个错误,在你过滤之前,你dataGridView使用它,

if (dataGridView1.Rows.Count > 0)
{
   //do filter codes here
}

希望这可以帮助。

于 2013-04-27T01:17:48.783 回答