2012-04-24 21 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); 
       } 
      } 
     } 


    }