Scotty Laughton
Scotty Laughton

Reputation: 53

How do I get WinForms Progress Bar to update while not visible, and then show at the updated value?

I have a project where I have a UserControl that is a download status panel and has a progress bar in it. The panel is hidden by default and shown when the user presses a button. In the background the progress bar is being updated as the download progresses.

The Problem

When I show the download panel the progress bar starts from zero and then animates up to its actual value, giving the illusion that this progress just happened as you opened the panel.

How can I get it to just show where it is, instead of starting from zero and then progressing up. I want the animation when the panel is open and progress is happening in real-time, but when I open the panel it should just start from where the current progress is.

I have a simple demo project that has the following code that replications the issue. Replication Steps are:

I have tried invalidating it using ProgressBar.Invalidate and then calling ProgressBar.Update but it makes no difference. I have searched all over the web but not seen this problem, all the problems I see are thread related, and this is not.

Any help would be much appreciated.

UserControl

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();

        this.Size = new Size(351, 48);
        this.Visible = false;

        progressBar1 = new ProgressBar();
        progressBar1.Location = new System.Drawing.Point(15, 22);
        progressBar1.Name = "progressBar1";
        progressBar1.Size = new System.Drawing.Size(322, 5);
        progressBar1.Minimum = 0;
        progressBar1.Maximum = 100;
        this.Controls.Add(progressBar1);
    }

    public void SetPogress(int progress)
    {
        progressBar1.Value = progress;
        progressBar1.Update();
    }
}

Form

public partial class Form1 : Form
{
    UserControl1 uc1 = null;

    public Form1()
    {
        InitializeComponent();

        // Add User Control with ProgressBar
        uc1 = new UserControl1();
        uc1.Location = new Point(50, 400);
        this.Controls.Add(uc1);

        // Add Set Progess Button
        var btn_SetProgress = new System.Windows.Forms.Button();
        btn_SetProgress.Location = new System.Drawing.Point(47, 46);
        btn_SetProgress.Name = "btn_SetProgress";
        btn_SetProgress.Size = new System.Drawing.Size(113, 23);
        btn_SetProgress.Text = "Set Progress to 50%";
        btn_SetProgress.Click += this.btn_SetProgress_Click;
        this.Controls.Add(btn_SetProgress);

        // Add Show Progess Button
        var btn_ShowProgress = new System.Windows.Forms.Button();
        btn_ShowProgress.Location = new System.Drawing.Point(47, 91);
        btn_ShowProgress.Name = "btn_ShowProgress";
        btn_ShowProgress.Size = new System.Drawing.Size(147, 23);
        btn_ShowProgress.Text = "Show Progress User Control";
        btn_ShowProgress.Click += this.btn_ShowProgress_Click;
        this.Controls.Add(btn_ShowProgress);
    }

    private void btn_SetProgress_Click(object sender, EventArgs e)
    {
        uc1.SetPogress(50);
    }

    private void btn_ShowProgress_Click(object sender, EventArgs e)
    {
        uc1.Visible = true;
    }
}

Upvotes: 1

Views: 3315

Answers (1)

Scotty Laughton
Scotty Laughton

Reputation: 53

Thanks to those who responded. I tried both suggested and the comment by @Jimi worked, so the final solution was to update the SetProgress method as follows:

    public void SetPogress(int progress)
    {
        if (!progressBar1.IsHandleCreated) { var h = progressBar1.Handle; }
        progressBar1.Value = progress;
    }

Upvotes: 1

Related Questions