【问题标题】:text on progressbar in c# [closed]c#中进度条上的文本[关闭]
【发布时间】:2011-11-24 15:08:25
【问题描述】:

我正在使用以下代码。

为什么不能正常运行?

private void Form1_Shown(object sender, EventArgs e)
{
    for (int i = 1; i <= 100; i++)
    {
        Application.DoEvents();
        Thread.Sleep(200);

        progressBar1.Refresh();
        progressBar1.Value = i;
        progressBar1.CreateGraphics().DrawString(i.ToString() + "%",
            new Font("Arial", (float)8.25, FontStyle.Regular),
            Brushes.Black, new PointF(progressBar1.Width / 2 - 10,
                progressBar1.Height / 2 - 7));


    }
}

更新:

为什么不总是显示文字?

【问题讨论】:

  • 你阻塞了 UI 线程。不要那样做。查看右侧的一些相关问题。
  • 此外,在大多数情况下,DoEvents = evil。 (hashvb.earlsoft.co.uk/Why_DoEvents_Are_Evil)
  • @JonSkeet- 只是告诉某人避免阻塞 UI 线程并没有帮助。 (说起来容易做起来难)。右边的相关问题也没有。我问了一个 follow-up question 来证明这个困难。

标签: c# progress-bar winapp


【解决方案1】:

这行得通——尽管我将线程睡眠设置为超过 200 毫秒。您的问题是您在 UI 线程中完成了工作,这样它就永远不会更新。为了更好的可见性,只需更改字体颜色:

 private void Form1_Load(object sender, EventArgs e)
{
  Task t = new Task(() => StartUpdate());
  t.Start();

  t.ContinueWith(task => Console.WriteLine("Done loading"));
}

 private void StartUpdate()
{
  for (int i = 1; i <= 100; i++)
  {
    UpdateProgressBar(i);
  }
}

private void UpdateProgressBar(int i)
{
  if (progressBar1.InvokeRequired)
  {
    progressBar1.Invoke(new Action<int>(UpdateProgressBar), new Object[] { i });
  }
  else
  {
    Thread.Sleep(200);
    progressBar1.Refresh();
    progressBar1.Value = i;
    progressBar1.CreateGraphics().DrawString(i.ToString() + "%", new Font("Arial",
                                          (float)10.25, FontStyle.Bold),
                                          Brushes.Red, new PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7));
  }
} 

【讨论】:

  • 为什么不总是显示文字?
  • 因为进度条和文字重叠了!?
  • 查看我的编辑 - 使用不与深蓝色重叠的另一种颜色。
【解决方案2】:

使用这个。有很好的方法可以做到这一点,但你的问题是它为什么不起作用,这是因为 Application.DoEvents();

    private void Main_Shown(object sender, EventArgs e)
    {
        for (int i = 1; i <= 100; i++)
        {
            progressBar1.Value = i;
            int percent = (int)(((double)(progressBar1.Value -progressBar1.Minimum) / (double)(progressBar1.Maximum - progressBar1.Minimum)) * 100);
            using (Graphics gr = progressBar1.CreateGraphics())
            {
                gr.DrawString(percent.ToString() + "%",  SystemFonts.DefaultFont, Brushes.Black, new PointF(progressBar1.Width / 2 - (gr.MeasureString(percent.ToString() + "%", SystemFonts.DefaultFont).Width / 2.0F), progressBar1.Height / 2 - (gr.MeasureString(percent.ToString() + "%", SystemFonts.DefaultFont).Height / 2.0F)));
            }
            System.Threading.Thread.Sleep(200);
        }
    }

【讨论】:

  • 您的 UI 也不会更新,因为 for 循环与主线程(负责更新您的 GUI)在同一个线程中。只需将其粘贴到一个空表单中并添加一个进度条 - 你会看到。
  • 这将是因为 Thread.Sleep() 方法。我已经在表格上尝试过了,它确实有效。睡眠中的值应该是 200 或更多。在否决我的事情之前你试过了吗?我打赌你没有,因为我有。
  • 刚才看到有人接受了我的回答。请在投票前尝试在虚拟应用程序中使用代码。我希望你能恢复它。
  • 我将您的代码按原样粘贴在一个空项目中。我看到的只是最后一个完整的进度条。该表格甚至不会在“进度阶段”出现。应该更新 GUI 的线程中的 Thread.Sleep 有什么好处?
  • 您使用的是什么表单事件?你在使用 Form_Load() 吗?看看我用了什么? Form_Shown()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多