应用BindingSource.Filter后产生Zero行的DataGridView错误?

时间:2013-04-27 00:40:39

标签: c# exception datagridview filter bindingsource

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

myDataGridView.DataSource = myBindingSource;

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

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

当我点击使myDataGridView显示至少1行的项目时,该工作正常。但是当我点击任何符合相应过滤表达式的0行的项目时,事情变得糟糕。 myDataGridView应该是正常的,但它会在一些对话框中抛出很多异常(因此出现)(代码编辑器窗口中的异常没有显示在黄色标记中),这是错误对话框的快照:

enter image description here

单击确定按钮后,它仍然显示另一个(同一个)对话框,....它继续显示许多对话框(具有相同的消息),直到它停止所有。我无法理解那是什么。我不知道你是否需要更多信息,但我希望你经历过类似的例外,并给我一些关于如何解决这个问题的建议。该对话框说明了DataError事件,但我不明白为什么这里有任何错误?请注意,如果在应用过滤器后我的dataGridView中至少有一行,则所有过滤器都会正常,只有在过滤器后面没有行时才会出现错误。

请帮帮我,非常感谢你!

2 个答案:

答案 0 :(得分:2)

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

我的规则是:

  1. 在应用过滤器之前,只需使用SuspendBinding()方法从BindingSource中挂起所有控件,如下所示:

    myBindingSource.SuspendBinding();

  2. 现在,只需按照以下方式应用过滤器:

    myBindingSource.Filter = "filter expression";

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

    myBindingSource.ResumeBinding();

  4. 就是这样。事实上,myBindingSource有许多绑定它的控件。也许这就是原因,但我仍然不太了解它。我敢打赌,如果myBindingSource只有绑定数据的myDataGridView,则不需要上面的所有3个步骤,只需在需要时立即应用过滤器(步骤2)。

    我希望这能帮助遇到,遇到并将遇到此问题的其他人。同样,我真的不明白为什么它有效,所以我希望有人可以在评论中解释它。我真的很感激。谢谢!

    更新

    我发现如上所述,在某些情况下可能会有另一个问题,最安全的解决方案是:

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

    2. 应用过滤器。

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

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

      真相

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

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

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

答案 1 :(得分:1)

因为没有什么可以过滤的,这就是你得到那个错误的原因, 在您过滤dataGridView之前,请使用此

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

希望这会有所帮助。