2010-11-06 54 views
1

我有一個創建新線程的按鈕。該線程包含以下內容。控件和線程

foreach (DataRow r in results.Rows) 
      { 
       var item = new ResultItem(this) 
           { 
            Image = r[1].ToString(), 
            Video = r[2].ToString(), 
            Title = r[3].ToString().Trim(), 
            Duration = r[4].ToString().Trim() 
           }; 


       SearchFlow.Controls.Add(item); 
      } 

我得到這個錯誤:在一個線程上創建的控件不能成爲不同線程上的控件的父元素。 ResItem是自定義的用戶控件,它是該項目的一部分,而不是第三方控件。有沒有解決的辦法?我如何將這個控件添加到新線程的流表中?

+0

@davisoa有正確的答案。這裏有一些如何使用'InvokeRequired'模式的選擇。 http://stackoverflow.com/questions/2367718/c-automating-the-invokerequired-code-pattern – 2010-11-06 23:21:32

+0

[「內部控件上的」跨線程操作無效「異常]的可能重複(http://stackoverflow.com/問題/ 974317 /跨線程操作 - 不有效的異常上-內對照) – 2010-11-07 08:52:58

回答

6

您只能觸摸創建它們的線程上的UI控件。這也意味着由後臺線程創建的任何控件都不能添加到您的UI中。

解決方案是僅使用UI(前景)線程創建控件。

做到這一點的一種方法是在表單上創建一個方法,以創建所需的控件,並檢查它是否爲前景線程。如果沒有,它可以將自己調整到前臺。這可以通過實施ISyncronizeInvoke的任何控制來完成。

private void Foo(object state) 
{ 
    if (this.InvokeRequired) 
    { 
     this.Invoke(Foo, state); 
     return; 
    } 
    // Do your creation of UI here... 
} 

請注意,此示例將阻止後臺線程,直到UI有一段時間來處理該方法。