“BindingSource不能是它自己的数据源” - 尝试从另一个类中的方法重置绑定源时出错
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“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
不能是自己的数据源。不要将DataSource
和DataMember
属性设置为引用BindingSource
的值。
如果我在我的DoWork Event
中这样做,那么我可以使用BeginInvoke method
重置控制线程本身的项目。
但实际上我正在尝试模拟我们的应用场景。所以我想以这种格式解决这个问题。
谁可以帮我这个事。
问题是你不能在gui线程之外的另一个线程中更新BindingSource
。这是因为BindingSource
将触发一些事件,这些事件随后会被您的数据网格视图接收,然后这些事件将开始自我更新,这将失败,因为它不会在gui线程上完成。
所以在你打电话给RunWorkerAsync()
之前你应该打电话给class1BindingSource.SuspendBinding()
,在你的RunWorkerCompleted
中你应该打电话给class1BindingSource.ResumeBinding()
。
同时确保在你的DoWork
中你不会在绑定源上调用任何方法(就像你使用bs.ResetItem(0)
一样)。
并删除此锁定语句。它根本没有任何意义(在你的例子中),如果你真的需要它(在你的真实代码中)考虑在你的类中使用一些private object _Gate = new Object();
来避免来自外部世界的任何死锁,因为bs.SyncRoot
是公开可用的。
我遇到了同样的问题: - 具有INotifyPropertyChanged元素的BindingSource - 一个更新元素的单独任务。
建议的解决方案SuspendBinding等不起作用。 BindingSource应该像IsInvokeRequired那样做。
幸运的是Ivan Stoev带来了对BindingSource进行子类化的绝妙想法,并做了与IsInvokeRequired类似的事情。谢谢伊万!
链接:Update BindingSource from a different Task
UpdateBindingSource()
不需要太多时间,所以不需要使用backgroundworker
。您可以在主线程中调用UpdateBindingSource()
。另外,在主线程中保持datagridview操作。
以上是关于“BindingSource不能是它自己的数据源” - 尝试从另一个类中的方法重置绑定源时出错的主要内容,如果未能解决你的问题,请参考以下文章