2012-04-24 54 views
1

現在,我知道大多數人看到這樣的問題時,他們會認爲「哦,使用代表」。那麼,我是使用代表。這是迄今爲止唯一拒絕與他們合作的控制措施。我也沒有使用BackgroundWorker。如何從線程設置ToolStripProgressBar的值?

我給自己寫了一個System :: Threading :: Thread的包裝類,因爲我知道我會很好地使用它們。我給班上的各種委託事件,以便它可以與UI線程交互。我一直在使用它,主要是爲了設置狀態欄的狀態。我還有一個未使用的進度條,所以我想添加它。我給它一個代表,但是當我運行它,它崩潰臭名昭著:

「System.InvalidOperationException」類型的未處理的異常出現在System.Windows.Forms.dll中

其他信息:跨線程操作無效:控制'' 從其創建線程以外的線程訪問。

我現在很困惑,因爲據我所知,我使用委託與我使用其他控件的方式相同。這是特別的嗎?我在網上搜索了很多,我得到的只是C#BackgroundWorker問題,這些問題並不適用於此。這裏是我的委託代碼:

委託:

delegate void    OnThreadProgressUpdateDel(int progress, String^ status); 

持有的事件變量:

OnThreadProgressUpdateDel^ m_updateProgressEvent; 

的情況下,勢必方式:

thread->OnThreadProgressUpdate += gcnew ObjectLoadThread::OnThreadProgressUpdateDel(this, &CObjectLoader::ProgressUpdate); 

這個活動叫做:

void CObjectLoader::ProgressUpdate(int progress, String^ status) 
{ 
    gGlobal->ProgramProgress->Maximum = 100; 
    gGlobal->ProgramProgress->Value = progress; //Crash here... 
    gGlobal->SetProgramStatus(status); 
} 

這裏所說的:

m_updateProgressEvent->Invoke(1, "Loading objects..."); 

什麼特別之處這個傻ToolStripProgressBar,使得它不想更新:(

使用C++ CLR,Windows窗體應用程序,在Microsoft Visual C++ 2008 Express版本。

回答

1

Windows控件想要從它們創建的同一個線程進行修改。根據控制&操作中,MDA或異常將不火,但它是迄今爲止最好遵循的標準:

if(InvokeRequired) control.Invoke();

模式每當一個線程和控制處理。

http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

+0

ToolStripProgressBar沒有一個'Invoke'方法。我可以使用'GetCurrentParent()'獲取'Invoke'方法嗎? 'InvokeRequired'也一樣。 – smoth190 2012-04-24 21:10:42

+0

@ smoth190您可以使用任何駐留在同一個線程上的組​​件,甚至宿主表單。 – 2012-04-24 21:12:39

+0

哦,很好。我將實施此方法以查看它是否可行。 – smoth190 2012-04-24 21:14:15

2

「ToolStripProgressBar沒有一個Invoke方法。」

你是對的;但是toolStripProgressBar.ProgressBar.Invoke和InvokeRequired確實存在,並按預期運行。

0

//使用下面的代碼Ahmad abbulkmailer。com

SetControlPropertyValue1(ProgressBar2,「value」,67);

delegate void SetControlValueCallback1(ToolStripProgressBar oControl,string propName,object propValue);如果(oControl.GetCurrentParent()。InvokeRequired)SetControlValueCallback1 d = new SetControlValueCallback1(SetControlPropertyValue1);如果(oControl.GetCurrentParent()。InvokeRequired)SetControlValueCallback1 d = new SetControlValueCallback1(SetControlPropertyValue1);如果(oControl.GetCurrentParent()。InvokeRequired){0} {0} oControl.GetCurrentParent()。Invoke(d,new object [] {oControl,propName,propValue}); } 其他{

  Type t = oControl.GetType(); 
      PropertyInfo[] props = t.GetProperties(); 

      foreach (PropertyInfo p in props) { 
       if (p.Name.ToUpper() == propName.ToUpper()) { 
        p.SetValue(oControl, propValue, null); 
       } 
      } 
     } 


    }