I'm trying to make a smooth progress bar that "loads" from 0 to 100 based on a time value (in seconds).
So far, I've got a method that sets up the progress bar's maximum value to 100 * loadTime
. Additionally, I've got a timer in my form, and its increment is 10 milliseconds
. The idea is that the progress bar's maximum, divided by the timer's increment, will equal the number of seconds the progress bar needs to load.
Unfortunately, there are some inconsistencies with my timer. For instance, if I set my timer's increment to 1000 milliseconds
and the bar's maximum to loadTime
, it will be somewhat consistent, but it doesn't do anything for the first second. It's also very jittery. At 100 milliseconds
and 10 * loadTime
, it's slightly more consistent, but still very jittery. 10 milliseconds
seems to be the sweet spot in terms of smoothness, however, if for instance, loadTime
is equal to 5
, it will load the progress bar in approximately 7
or 8
seconds.
I have also tried setting the timer's increment to 1
, and my bar's maximum to 1000 * loadTime
, however, this just makes it slower, and results in times of 10-13 seconds, when it should be 5
for instance.
Why's this the case? Can anything be done about it?
DisplayTimeProgressBar.cs
(credit to Crispy's answer)
[DesignerCategory("code")]
public class DisplayTimeProgressBar : ProgressBar
{
public DisplayTimeProgressBar()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
Rectangle rec = e.ClipRectangle;
rec.Width = (int)(rec.Width * ((double)Value / Maximum));
rec.Height = rec.Height;
e.Graphics.FillRectangle(Brushes.Aquamarine, 0, 0, rec.Width, rec.Height);
}
}
Form.Designer.cs
private System.Windows.Forms.Timer progressBarTimer = new System.Windows.Forms.Timer(this.components);
private DisplayTimeProgressBar displayTimeProgressBar = new DisplayTimeProgressBar();
Form.cs
private void loadBar(int timeToDisplay)
{
this.displayTimeProgressBar.Visible = true;
this.displayTimeProgressBar.Maximum = timeToDisplay * 100;
this.progressBarTimer.Start();
}
private void progressBarTimer_Tick(object sender, EventArgs e)
{
if (this.displayTimeProgressBar.Value >= this.displayTimeProgressBar.Maximum)
{
this.displayTimeProgressBar.Value = 0;
this.displayTimeProgressBar.Visible = false;
this.progressBarTimer.Stop();
}
else
{
this.displayTimeProgressBar.Value++;
}
}
The following is a visual demonstration of my issue. The parameter loadTime
has been set to 5
(5 seconds). In this demo, the timer's increment is 10
, and the bar's maximum is 500
.