WinForms根据其属性不绘制ProgressBar

时间:2017-07-03 12:55:33

标签: c# winforms progress-bar

我正在使用ProgressBar来监控DataGridView的人口数量,其中包含从数据库中检索到的数据,以及位于其左侧的Label

对此没什么好看的。数据检索发生在DoWork的{​​{1}}处理程序中,此时BackgroundWorker采用Marquee样式,而ProgressBar则显示通用的“正在加载...”。加载完成后,Label的{​​{1}}处理程序会逐行向ProgressChanged添加行,而BackgroundWorkerDataGridView会显示进度。我正在使用的代码如下:

ProgressBar

Label始终正确显示,通过调试,我发现*code that adds row* if (e.ProgressPercentage > 0) pbrProgress.Value = e.ProgressPercentage - 1; pbrProgress.Value = e.ProgressPercentage; lblProgress.Text = e.ProgressPercentage + "/" + pbrProgress.Maximum; 也具有正确的LabelProgressBar属性。但是,Value实际上并没有开始显示进度(绿色填充),直到达到第10个结果左右。当最后一个结果添加到Maximum时,它还远没有完整。

图片: Beginning Near the end

我尝试在代码末尾添加ProgressBar,并使用自DataGridView属性设置为pbrProgress.Refresh();的自定义ProgressBar,但无济于事。

真的,我发现的唯一解决方案是在每次调用DoubleBuffered后让线程休眠80ms。还有比这更好的方法吗?

3 个答案:

答案 0 :(得分:0)

可能是,进度条没有响应,因此它不会自行重绘。

应该在DoWork - BackgroundWorker的事件而不是ProgressChanged - 事件中调用此类工作密集的内容。 ProgressChanged - 事件是您要更改ProgressBar

的地方

所以你可以做某事。像这样:

private static void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            int size = 100;

            // Function to Setup your Progressbar
            form.SetUpProgressBar(size);

            // hard work...
            for (int i = 0; i < size; i++)
            {
                Thread.Sleep(100);

                // Fires the Worker_ProgressChanged Event with the Percentage of the current progress
                (sender as BackgroundWorker).ReportProgress(i + 1);
            }
        }

        private static void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Update the ProgressBar
            form.progressBar1.Value = e.ProgressPercentage;
        }

        private static void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Hey I'm done!");
        }

注意:

在使用worker.ReportProgress()之前,您必须致电worker.WorkerReportsProgress = true;,否则您将遇到错误。

ProgressChanged内的方法调用需要调用(如果您不知道如何执行此操作,请点击我。)

您应该像这样使用BackgroundWorker:

1)DoWork用于繁重的工作,必须从GUI线程中分离出来 2)ProgressChanged向ProgressBar报告进度 3)RunWorkerComplete表示您现在已完成(关闭Windows等)

您可以向BackgroundWorker提供一些值,如下所示:worker.RunWorkerAsync(value);并通过(e.Argument as int) - 事件中的DoWork(或其他)进行访问。

希望这会有所帮助:)

- Maddin

答案 1 :(得分:0)

嗯,事实证明解决方案非常简单。

而不是

if (e.ProgressPercentage > 0)
    pbrProgress.Value = e.ProgressPercentage - 1;
pbrProgress.Value = e.ProgressPercentage;

必须是

pbrProgress.Value = e.ProgressPercentage;
if (e.ProgressPercentage > 0)
      pbrProgress.Value = e.ProgressPercentage - 1;

我不知道为什么它以某种方式工作而不是另一种方式。也许是因为进度条值仅在第一次迭代时改变一次?

无论如何,这不再是问题。

答案 2 :(得分:-1)

简单:在设置Application.Doevents()的{​​{1}}属性后添加Value