2011-06-15 96 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