I want to display text on a ProgressBar
, (without all the nonsense of a custom progress bar). This is not hard to do, and does not involve the OnPaint
method -- as demonstrated with button1 of the following code. However, this method blocks the UI thread, which is evil.
Unfortunately, my best stab at an asynchronous approach causes the text to flicker, which is very annoying.
Can somebody show me how to update the text asynchronously without the flicker?
(To run the following code, just paste it into a new project containing a Form with 3 Buttons and 3 ProgressBars).
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Threading;
namespace ProgBarTest //change namespace in Program.cs accordingly
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//This method will block the main UI thread
// (thus freezing the other buttons)
StartUpdate(this.progressBar1);
}
private void button2_Click(object sender, EventArgs e)
{
//this method (and the next) don't block the UI, and can be used concurrently,
// but the text flickers
Task t = new Task(() => StartUpdate(this.progressBar2));
t.Start();
}
private void button3_Click(object sender, EventArgs e)
{
Task t = new Task(() => StartUpdate(this.progressBar3));
t.Start();
}
private void StartUpdate( ProgressBar progBar)
{
for (int i = 1; i <= 100; i++)
{
UpdateProgressBar(i, progBar);
Thread.Sleep(100);
}
}
private void UpdateProgressBar(int i, ProgressBar progBar)
{
if (progBar.InvokeRequired) //for use with background Task
{
progBar.Invoke(new Action<int, ProgressBar>(UpdateProgressBar),
new Object[] { i, progBar });
}
else
{
//set progress bar:
progBar.Value = i;
progBar.Refresh();
//set status label:
string percentStr = i.ToString() + "%";
PointF location = new PointF(progBar.Width / 2 - 10, progBar.Height / 2 - 7);
using (Graphics gr = progBar.CreateGraphics())
{
gr.DrawString(percentStr, new Font("Arial",10), Brushes.Red, location );
}
}
}
}
}