2011-06-15 102 views
2

我试图从背景工作线程访问主线程上的UI控件。我知道这是一个众所周知的问题,但我无法找到任何关于如何从背景线程访问datagridview的信息。我知道做一个列表框的代码是:C#:从背景线程访问datagridview1

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中的列表框控件?

由于

回答

1

Invoke方法上以相同的方式作为ListBoxDataGridView作品。

下面是一个示例,其中DataGridView最初绑定到BindingList<items>,我们创建一个新列表并绑定到该列表。这应该等同于您要求将DataTable从您的电话拨入Oracle并将其设置为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,像这样的工作列表框经过:

backgroundWorker1.RunWorkerAsync(this.listBox2); 

然后你可以施放arguments对象的DoWork的事件处理程序中:

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!    
} 
+0

我不想要使用runworker完成,因为我的datagrid代码在背景中。我的backgrounder线程实际上调用另一个想要输出到datagridview的方法。我真的不明白你在做什么?我想调用一个委托方法并将它传递给我希望gridview显示的信息。我不认为你的方法做到了这一点 – hWorld 2011-06-16 13:05:00

+0

@Dominique - 我的方法更新了datagridview,但是有很多这样做的方法,我无法真正给你一个例子来匹配你所需要的,没有更多的信息。如果你不是在后台线程中工作,你可以使用代码来编辑你的问题吗? – 2011-06-16 13:11:52

+0

@Dominique - 你可以做的一个例子就是使用绑定源和调用。 – 2011-06-16 13:14:01