使用进度条在statusstrip中更新标签

时间:2014-11-11 08:13:03

标签: c# winforms progress-bar

我一直在vc#express 2013中开发一个Windows窗体应用程序。我有一个statusstrip控件,我有一个标签和一个进度条。我想在标签中显示进度条的进度,但它没有使用进度条值更新。只有当进度条完成时才会更新,即当值为100且作业结束时。奇怪的是,进度条已更新,但标签不是......任何想法可能会发生在这里?顺便说一句,我在我自己的代码中提出了一个进度事件,并且相应地更新了进度... 感谢

我在MGFDataHandler类中引发事件ProgressTick

if ((hundredthValue*progressMultiplier == lineCounter) || (lineCounter==totalLines))
            {
                //Raise the progress bar event!
                EventHandler handler = ProgressTick;                                        
                if (handler != null)
                {
                    handler(this, e);
                }
                progressMultiplier++;
            }

然后我按照以下方式在windowsform中处理它:

void msDataHandler_ProgressTick(object sender, EventArgs e)
    {
        var progress = (int)((MGFDataHandler)sender).progressMultiplier;            
        if (progress < 100)
        {
            this.progressStatusString.Text = "Progress: " + progress + "%";                
            this.progressBar.Visible = true;
            this.progressBar.Value = progress;
        }            
        else 
        {
            this.progressStatusString.Text = "Done";
            this.filterMSDataToolStripMenuItem.Enabled = true;                
        }
    }

启动整个事件的函数在windowsform_activated事件中,而MGFDataHandler对象是windowsform的一个属性。

private void GlycoMSPipelineMainFrame_Activated(object sender, EventArgs e)
    {
        switch (this.whoActivatedMe)
        {
            case WhoActivatedMe.MSFilterWizard:
                {
                    this.whoActivatedMe = WhoActivatedMe.Me;
                    foreach (String currentmgffilename in this.currentMGFFileNames)
                    {
                        mgfDataHandler.Filter_MS_Data(currentmgffilename);
                    }                        
                    this.populateTreeViews();
                    break;
                }
            default:
                {
                    break;
                }
        }
    }

提升事件的是Filter_MS_Data。

3 个答案:

答案 0 :(得分:0)

我确实需要更多信息来获得完整的答案,但是这个方向对我来说非常清楚。

问题是你可能在同一个线程中做了所有事情。当你有一份大工作时,你需要使用后台线程来完成工作,让主线程(即UI线程)处理UI。

这是一个很大的主题,我只是在这里略读,所以首先阅读以下链接并尝试为您的工作创建一个线程并自己调用进度条的更新。如果不成功,则发布一个包含更多信息的新问题。

您应该阅读的链接是:

答案 1 :(得分:0)

尝试使用后台工作程序(在System.componentModel中找到)来运行您正在执行的任务。更新标签或进度时,您需要检查是否需要调用。

像这样的东西。

If (label.InvokeRequired) { 
label.Invoke(new MethodInvoker(delegate
 { 
label.Text = progress.Value;
 });
}

需要调用以防止交叉线程操作,这反过来又会产生竞争条件。

原谅我在手机上输入的格式。

您需要使用后台工作人员执行填充。我认为这将解决您的问题。

编辑: 后台工作程序提供了一个将在另一个线程上运行的do work事件。它还提供完成的事件,以便您知道任务何时完成。

我认为这里发生的事情是你的程序在ui线程上执行工作,这会阻止ui完全更新。

答案 2 :(得分:0)

我意识到这是一个非常老的问题,但是我在VS2019中发现了同样的问题。我发现,可以添加标签和ProgressBar的容器的Refresh方法,而不是添加线程。

void msDataHandler_ProgressTick(object sender, EventArgs e)
    {
        var progress = (int)((MGFDataHandler)sender).progressMultiplier;            
        if (progress < 100)
        {
            this.progressStatusString.Text = "Progress: " + progress + "%";                
            this.progressBar.Visible = true;
            this.progressBar.Value = progress;
        }            
        else 
        {
            this.progressStatusString.Text = "Done";
            this.filterMSDataToolStripMenuItem.Enabled = true;                
        }
        this.progressStatusString.Owner.Refresh();
    }