我试图从后台工作线程访问主线程上的ui控件。我知道这是一个众所周知的问题,但我找不到任何有关如何访问datagridview的信息,特别是从后台程序线程。我知道列表框的代码是:
private delegate void AddListBoxItemDelegate(object item);
private void AddListBoxItem(object item)
{
//Check to see if the control is on another thread
if (this.listBox1.InvokeRequired)
this.listBox1.Invoke(new AddListBoxItemDelegate(this.AddListBoxItem), item);
else
this.listBox1.Items.Add(item);
}
如何使datagridview控件工作?此外,上述方法仅适用于一个列表框(listBox1),有没有办法使一个方法适用于主ui中的所有列表框控件?
由于
答案 0 :(得分:1)
Invoke
上的DataGridView
方法的工作方式与ListBox
相同。
以下是DataGridView
最初绑定到BindingList<items>
的示例,我们创建一个新列表并绑定到该列表。这应该等同于您从调用Oracle获取DataTable
并将其设置为DataSource
的要求。
private delegate void SetDGVValueDelegate(BindingList<Something> items);
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Some call to your data access infrastructure that returns the list of itmes
// or in your case a datatable goes here, in my code I just create it in memory.
BindingList<Something> items = new BindingList<Something>();
items.Add(new Something() { Name = "does" });
items.Add(new Something() { Name = "this" });
items.Add(new Something() { Name = "work?" });
SetDGVValue(BindingList<Something> items)
}
private void SetDGVValue(BindingList<Something> items)
{
if (dataGridView1.InvokeRequired)
{
dataGridView1.Invoke(new SetDGVValueDelegate(SetDGVValue), items);
}
else
{
dataGridView1.DataSource = items;
}
}
在我成功使用DataGridView
的测试代码中,将该数据源设置为DoWork事件处理程序中生成的数据源。
您也可以使用RunWorkerCompleted
回调,因为它被编组到UI线程。一个例子如下:
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
dataGridView1[0, 0].Value = "Will this work?";
}
关于问题的第二部分,有几种方法可以实现这一目标。最明显的是在调用BackGroundWork时传入你想要处理的ListBox,如下所示:
backgroundWorker1.RunWorkerAsync(this.listBox2);
然后你可以在DoWork事件处理程序中强制转换arguments对象:
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ListBox l = e.Argument as ListBox;
// And now l is whichever listbox you passed in
// be careful to call invoke on it though, since you still have thread issues!
}