“BindingSource不能是它自己的数据源” - 尝试从另一个类中的方法重置绑定源时出错

时间:2013-01-10 12:57:44

标签: winforms datagridview thread-safety backgroundworker bindingsource

我们使用DataGridview绑定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重置控件线程中的项目。

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

任何人都可以帮助我。

3 个答案:

答案 0 :(得分:14)

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

因此,在致电RunWorkerAsync()之前,您应致电class1BindingSource.SuspendBinding(),在RunWorkerCompleted内,您应致电class1BindingSource.ResumeBinding()

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

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

答案 1 :(得分:2)

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

建议的解决方案SuspendBinding等没有用。 BindingSource应该像IsInvokeRequired那样做。

幸运的是,Ivan Stoev带来了对BindingSource进行子类化的绝妙想法,并做了与IsInvokeRequired类似的事情。谢谢伊万!

链接:Update BindingSource from a different Task

答案 2 :(得分:0)

UpdateBindingSource()不需要花费很多时间,因此无需使用backgroundworker。您可以在主线程中调用UpdateBindingSource()。 另外,将datagridview操作保持在主线程中。