【问题标题】:DataGridView error after applying BindingSource.Filter which resulting Zero rows?应用 BindingSource.Filter 后 DataGridView 错误导致零行?
【发布时间】:2013-04-21 06:12:36
【问题描述】:

我不明白为什么会发生这种情况。我有一个 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 行,则所有过滤器都会正常,只有在过滤器后没有行时才会发生错误。

请帮帮我,非常感谢您!

【问题讨论】:

    标签: c# exception datagridview filter bindingsource


    【解决方案1】:

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

    我的规则是:

    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(当然还有其他的这里没有提到)。这种关系是我所怀疑的,但我仍然不清楚它为什么以及如何引发错误。如果不使用绑定并手动分配/更新所有值,则不会出现任何错误。绑定有时非常复杂。

    【讨论】:

    • 谢谢,那样不太好。有时我们只知道这样做会起作用(或者至少是目前唯一一个可行的解决方案),但我们不太了解它为什么会起作用。这是我的情况,我只想在这里分享,希望有人可以留下一些解释性评论,甚至欢迎更好的答案。谢谢!
    【解决方案2】:

    因为没有要过滤的内容,这就是您收到该错误的原因, 在你过滤你之前dataGridView使用这个,

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

    希望这会有所帮助。

    【讨论】:

    • 不,不是这样,我的datagridviews在应用过滤器之前有一些行,过滤后它应该是空的。为什么其他情况(结果集中至少有 1 行)有效???唯一改变的是过滤器表达式。但是我自己解决了这个问题,请看我的回答,我真的不明白为什么它有效,但它确实有效! =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2016-08-31
    • 2022-08-20
    • 1970-01-01
    相关资源
    最近更新 更多