How to implement a progress bar in windows forms C#?

19,174

Solution 1

Your program has many loops,since it will be difficult to get the increment value and increment the progress bar value in each loop iteration.You could set the progress bar maximum to 100,Then divide 100 by the number of loops you have say X.

So the trick would be to fill the progress bar by this value when each loops completes

and yes you should put this code in backgroundworker's DoWork() otherwise it will freeze the form.Also there is no need for a timer.

Solution 2

This is how I have used Progress Bar in my application.

private void btnNext_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.ProgressChanged += (se, eventArgs) => {
            this.progressBar.Maximum = 100;
            this.progressBar.Minimum = 0;
            this.progressBar.Value = eventArgs.ProgressPercentage;
            lblStatus.Text = eventArgs.UserState as String;
            lblPercentage.Text = String.Format("Progress: {0} %", eventArgs.ProgressPercentage);
        };

worker.DoWork += (se, eventArgs) => {
    int progress = 0;
    ((BackgroundWorker)se).ReportProgress(progress, "Initializing the files...");

    //Process that takes a long time
    //Formula to calculate Progress Percentage 
    //This is how I calculated for my program. Divide 100 by number of loops you have

    int findPercentage = ((i + 1) * 100) / salesHeaderArr.Count;
    progress = 0;
    progress += findPercentage / 2;

    //Report back to the UI
    string progressStatus = "Importing Sales Header... (" + getSourceFileName(sourceFilePath) + ")";     
    ((BackgroundWorker)se).ReportProgress(progress, progressStatus);

   //After Iterating through all the loops, update the progress to "Complete"
   ((BackgroundWorker)se).ReportProgress(100, "Complete...");
};
worker.RunWorkerCompleted += (se, eventArgs) =>
        {
            //Display smth or update status when progress is completed
            lblStatus.Location = new Point(20, 60);
            lblStatus.Text = "Your import has been completed. \n\nPlease Click 'Finish' button to close the wizard or \n'Back' button to go back to the previous page.";
            lblPercentage.Visible = false;
            progressBar.Visible = false;
            btnBack.Enabled = true;
            btnFinish.Enabled = true;
        };

        worker.RunWorkerAsync();
}
Share:
19,174
Aung Kaung Hein
Author by

Aung Kaung Hein

Updated on June 04, 2022

Comments

  • Aung Kaung Hein
    Aung Kaung Hein almost 2 years

    I have my own solution to import monthly sales data in my windows form application. When a user click on import button, the program is actually running but it looks like it's not responding. The process takes a long time about 5 minutes.

    So, I'd like to implement a progress bar with status strip label to display as an user interface and let the users know how much the task is done. This is also my first time using a progress bar in my program. So, I read through some tutorials which show how to use it. Some people use progress bar with background worker and timer.

    But I don't understand where I should use the solution that I have. In background worker DoWork() event? I don't want to fake it by abusing the progress bar like setting the progressBar.Maximum = 100, progressBar.Value = 0 and as long as the timer is ticking increasing the value by 5. The progress bar must report the actual progress while the program is running.

    The following is the solution I am using now to import the data:

    private void btnImport_Click(object sender, EventArgs e)
        {
            if (lsbxBrowsedFiles.Items.Count != 0)
            {
                ArrayList salesHeaderArr = new ArrayList();
                ArrayList salesDetailArr = new ArrayList();
    
                int i = 0;
                while (i < browsedXmlFileList.Count)
                {
                    if (browsedXmlFileList[i].ToUpper().EndsWith("SALESHEADER.XML"))
                    {
                        salesHeaderArr.Add(browsedXmlFileList[i]);
                    }
                    if (browsedXmlFileList[i].ToUpper().EndsWith("SALESDETAIL.XML"))
                    {
                        salesDetailArr.Add(browsedXmlFileList[i]);
                    }
                    i++;
                }
    
                if (selectedFileIsNotInDestinationFolder(salesHeaderArr, salesDetailArr) == true)
                {
                    i = 0;
                    while (i < salesHeaderArr.Count)
                    {
                        SalesHeader salesHeader = new SalesHeader();
                        string sourceFilePath = salesHeaderArr[i].ToString();
                        readXMLFiles(sourceFilePath, SALES_HEADER);
                        SalesHeader salesCheck = (SalesHeader)salesHeaderList[0];
                        string checkOutletCode = salesCheck.OutletCode;
                        DateTime checkBusDate = salesCheck.BusinessDate.Value;
                        if (SalesHeader.IsThisRowAlreadyImportedInSalesHeader(checkOutletCode, checkBusDate) == false)
                        {
                            salesHeader.ImportSalesHeader(salesHeaderList);
                            salesHeader.CreateImportDataLog(getDestinationFilePath(sourceFilePath),
                                DateTime.Now, salesHeaderList.Count, SALES_HEADER);
                        }
                        else
                        {
                            string errorDate = checkBusDate.ToString("dd MMMM, yyyy");
                            MessageBox.Show("Selected XML File with BusinessDate: " + errorDate + " has been already imported.",
                                "ABC Cafe Import Sales Wizard");
                            MessageBox.Show("Please select a file which has not been imported!",
                                "ABC Cafe Import Sales Wizard");
                            return;
                        }
                        MoveXMLFiletoDestinationFolder(sourceFilePath);
                        i++;
                    }
                    i = 0;
                    while (i < salesDetailArr.Count)
                    {
                        SalesDetail salesDetail = new SalesDetail();
                        string sourceFilePath = salesDetailArr[i].ToString();
                        readXMLFiles(sourceFilePath, SALES_DETAIL);
                        SalesDetail salesCheck = (SalesDetail)salesDetailList[0];
                        string checkOutletCode = salesCheck.OutletCode;
                        DateTime checkBusDate = salesCheck.BusinessDate.Value;
                        if (SalesDetail.IsThisRowAlreadyImportedInSalesDetail(checkOutletCode, checkBusDate) == false)
                        {
                            salesDetail.ImportSalesDetail(salesDetailList);
                            salesDetail.GenerateCarryForward(salesDetailList);
                            salesDetail.CalculateImportInventoryBalance(salesDetailList);
                            salesDetail.CreateImportDataLog(getDestinationFilePath(sourceFilePath), DateTime.Now, salesDetailList.Count, SALES_DETAIL);
                        }
                        else
                        {
                            string errorDate = checkBusDate.ToString("dd MMMM, yyyy");
                            MessageBox.Show("Selected XML File with BusinessDate: " + errorDate + " has been already imported.",
                                "ABC Cafe Import Sales Wizard");
                            MessageBox.Show("Please select a file which has not been imported!",
                                "ABC Cafe Import Sales Wizard");
                            return;
                        }
                        MoveXMLFiletoDestinationFolder(sourceFilePath);
                        i++;
                    }
                    MessageBox.Show("Import has been successfully completed!",
                    "ABC Cafe Import Sales Wizard");
                    clearListBoxItems();
                    lblMessage.Visible = false;
                }
                //Abort the import operation here!
                else
                {
                    MessageBox.Show("Please select a file which has not been imported!",
                    "ABC Cafe Import Sales Wizard");
                    clearListBoxItems();
                    lblMessage.Visible = false;
                }
            }
            else
            {
                MessageBox.Show("Please select XML files to import!", 
                    "ABC Cafe Import Sales Wizard");
            }
        }
    

    Any help will be very much appreciated!