Using a Progress bar on Form Load

12,394

Solution 1

Since this is winforms, i'd recommend using a BackgroundWorker.

Basic example:

bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.ProgressChanged += new DoWorkEventHandler(bgWorker_ProgressChanged);
bgWorker.RunWorkerAsync(//pass in object to process)

Which would then kickoff:

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
     //Do all of your work here
     bgWorker.ReportProgress(); //percent done calculation  
}

Then the Progress changed event would fire to update the UI safely:

private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
     progressBar.Value = e.ProgressPercentage;
}

Solution 2

Add a backgroundWorker1 to your form.

Then add a YourForm_Shown event

private void YourForm_Shown(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

Add on form's constructor after InitializeComponent()

backgroundWorker1.WorkerReportsProgress = true;
// This event will be raised on the worker thread when the worker starts.
backgroundWorker1.DoWork += new
    DoWorkEventHandler(backgroundWorker1_DoWork);
// This event will be raised when we call ReportProgress.
backgroundWorker1.ProgressChanged += new
    ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);

And last add the voids of backgroundWorker1:

void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // The progress percentage is a property of e
    progressBar1.Value = e.ProgressPercentage;
}

And:

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 1; i <= n; i++)
    {
        //getting data from DB.
        dataGridView1.Rows.Add(....);
        //Adding that data to a datagrid -- parametrs removed.
        backgroundWorker1.ReportProgress(i);
        // Simulate long task                 
    }
}

Solution 3

This is simple mockup to show you how to work with background worker:

First in your OnLoad create background worker and attach 2 events to it:

var bw = new BackgroundWorker();            
bw.RunWorkerCompleted +=
    new RunWorkerCompletedEventHandler(WorkCompleted);
bw.DoWork += new DoWorkEventHandler(DoWork);
bw.RunWorkerAsync(data); // Assume data is list of numbers.
private void WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
// After work completed remove event handlers and dispose.
{
    var bw = (BackgroundWorker)sender;
    bw.RunWorkerCompleted -= WorkCompleted;
    bw.DoWork -= DoWork; bw.Dispose();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
    var data = (List<int>)e.Argument;
    foreach (var number in data)
    {
        if (progressBar1.InvokeRequired)
        {
            progressBar1.Invoke((MethodInvoker)delegate
                { this.ProcessNumber(number); });                    
        }
        else
        {
            ProcessNumber(number);
        }
    }
}
private void ProcessNumber(int i)
{
    progressBar1.PerformStep();
    //do something with i
}
Share:
12,394
Arashdn
Author by

Arashdn

Updated on June 13, 2022

Comments

  • Arashdn
    Arashdn almost 2 years

    I am trying to Design a WinForms control in C# which will get some data from a database while it's loading.

    I want to use a progress bar to show the progress.

    I tried this code (and also many others):

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        this.Show();
        
        progressBar1.Value = 10;
        int n;
    
        n = 50;//number of records in DB ,
        double progress = 0;
        double progstep = 25 / n;
        for (int i = 1; i <= n; i++)
        {
            //getting 
            if (progress <= 100)
                progressBar1.Value = (int)progress;
        }
    
        progressBar1.Value = 35;
    
        n = 100;//number of records in DB for another data reading from DB ,
        progress = 35;
        progstep = 65 / n;
        for (int i = 1; i <= n; i++)
        {
            //getting data from DB
            dataGridView1.Rows.Add(....);
            //Adding that data to a datagrid -- parametrs removed.
            progress += progress;
            if (progress <= 100)
                progressBar1.Value = (int)progress;
        }
    }
    

    But, the problem is that the form will wait until data reading progress is completed, and I can see just a full progress bar and all data loaded.

    What should I do to fix this?

    • bash.d
      bash.d almost 11 years
      Use threading to make this a background-progress.
    • kostas ch.
      kostas ch. almost 11 years
      Try to use backroundWorker.
    • Arashdn
      Arashdn almost 11 years
      @bash.d , As I will use a datagrid on the form , I don't know how to done this with a background worker or threading ..
    • lightbricko
      lightbricko almost 11 years
    • bash.d
      bash.d almost 11 years
      You can pass a worker-method to a thread or background-worker and so determine what happens in your thread. Use this as a start.