7

我们正在绑定一个DataGridviewusing BindingSource。所以在主线程中我们给出了这样的。

            class1BindingSource = new BindingSource();
            class1BindingSource.DataSource = class1List;  
            this.dataGridView1.DataSource = class1BindingSource;

之后,我在表单中放置了一个后台工作人员,并在单击按钮时触发。

即在按钮中单击

this.backgroundWorker1.RunWorkerAsync()

BackgroundWorker DoWork Event我试图BindingSource通过尝试更新DataGridview.

所以BindingSource重置是在另一个类的方法中完成的。

DoWork Event

Class2 cl2 = new Class2();
cl2.UpdateBindingSource(class1BindingSource);

UpdateBindingSource Method

public void UpdateBindingSource(BindingSource bs)
        {
            Class1 c1 = bs.Current as Class1;    
            for (int i = 0; i < 1000; i++)
            {
                lock (bs.SyncRoot)
                {
                    c1.MyProperty1 = i;
                    bs.ResetItem(0);
                }
            }
        }

现在我遇到了一个异常,比如BindingSource不能是它自己的数据源。不要将DataSourceDataMember属性设置为引用回 的值BindingSource

如果我在我的中这样做,DoWork Event那么我可以使用在控制线程本身中重置项目BeginInvoke method

但实际上我正在尝试模拟我们的应用场景。所以我想以这种格式解决这个问题。

谁可以帮我这个事。

4

3 回答 3

17

问题是您无法BindingSource在 gui 线程以外的线程中更新 a 。这是因为,BindingSource将触发一些事件,然后您的数据网格视图将接收这些事件,然后开始自我更新,这将失败,因为它不会在 gui 线程上完成。

所以在你打电话之前RunWorkerAsync()你应该打电话class1BindingSource.SuspendBinding(),在你的内部RunWorkerCompleted你应该打电话class1BindingSource.ResumeBinding()

还要确保在您的内部您DoWork不会调用绑定源上的任何方法(就像您对 所做的那样bs.ResetItem(0))。

并删除此锁定语句。它根本没有任何意义(在你的例子中),如果你真的需要它(在你的真实代码中)考虑private object _Gate = new Object();在你的类中使用一些来避免来自外部世界的任何死锁,原因bs.SyncRoot是公开的。

于 2013-01-11T08:45:51.157 回答
3

我遇到了同样的问题: - BindingSource 的元素带有 INotifyPropertyChanged - 更新元素的单独任务。

建议的解决方案 SuspendBinding 等不起作用。BindingSource 应该完成类似 IsInvokeRequired 的操作。

幸运的是,Ivan Stoev 提出了将 BindingSource 子类化并执行与 IsInvokeRequired 类似的事情的绝妙想法。谢谢伊万!

链接:从不同的任务更新 BindingSource

于 2015-10-01T15:01:26.183 回答
0

UpdateBindingSource()不需要太多时间,所以不需要使用backgroundworker. UpdateBindingSource()您可以在主线程中调用。此外,将 datagridview 操作保留在主线程中。

于 2018-09-06T09:31:46.827 回答