我正在使用Bindinglist<Object>
和DataGridView来填充对象列表并将其显示在DataGridView中。
我的列表由另一个线程填充而不是DataGridView线程,因此我在GUI线程(DataGridView上的线程)中编写的Invoke
方法中使用ListChanged()
方法。
现在,只要我将Object添加到主线程中的BindingList(处理列表) - DataGridView已更新确定,但是,当我尝试在BindingList上运行Clear()
方法时 - 我的ListChanged()
方法运行,但是,我仍然得到例外:Cross-thread operation not valid: Control 'dgv' accessed from a thread other than the thread it was created on
。为什么我得到这个例外?我已经在ListChanged()
方法中处理了GUI,没有?
代码:
myBindingList.ListChanged += new ListChangedEventHandler(Events_ListChanged);
BindingSource source = new BindingSource(myBindingList, null);
dgv.DataSource = source;
在主线程中运行Clear()
方法:
myBindingList.Clear();
我的ListChanged()
方法:
void Events_ListChanged(object sender, ListChangedEventArgs e)
{
if (dgv.InvokeRequired)
{
dgv.Invoke(new UpdateDataGridItemDelegate(this.Events_ListChanged), sender, e);
return;
}
else
{
source.ResetBindings(false);
lblTotal.Text = myBindingList.Count.ToString();
}
}
我强调:当我将对象添加到绑定列表时,它运行良好并且我没有得到异常(我从运行Clear()
方法的同一个线程中执行此操作),但是我运行Clear()方法,它抛出了“Cross Thread”异常。任何想法为什么?
答案 0 :(得分:1)
我将ListChanged()
方法更改为以下内容并且有效!:
void Events_ListChanged(object sender, ListChangedEventArgs e)
{
if (dgv.InvokeRequired)
{
dgv.Invoke(new UpdateDataGridItemDelegate(this.Events_ListChanged), sender, e);
return;
}
else
{
if (e.ListChangedType == ListChangedType.Reset)
{
dgv.DataSource = null;
source = new BindingSource(myBindingList, null);
dgv.DataSource = source;
}
else
source.ResetBindings(false);
lblTotal.Text = myBindingList.Count.ToString();
}
}
我取消绑定DataGridView的数据源,并在重置BindingList时将其再次绑定到BindingList。