在表单加载上使用进度条

时间:2013-06-18 09:00:23

标签: c# winforms progress-bar

抱歉我的英文不好

我正在尝试在C#中设计一个Win Form,它将在加载时从数据库中获取一些数据

我想使用进度条显示阅读数据进度

我尝试了这段代码(以及其他许多代码)

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;
    }

}

但问题是,Form会等待,直到数据读取进度完成,我只能看到一个完整的进度条和所有加载的数据。

我该怎么做才能解决这个问题?

由于

4 个答案:

答案 0 :(得分:5)

由于这是winforms,我建议使用BackgroundWorker

基本示例:

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

然后开始:

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

然后,Progress change事件将触发安全地更新UI:

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

答案 1 :(得分:2)

这是一个简单的模型,向您展示如何使用backround worker:

首先在OnLoad创建后台工作人员并向其附加2个事件:

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
}

答案 2 :(得分:2)

在表单中添加backgroundWorker1

然后添加YourForm_Shown事件

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

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);

最后添加了backgroundWorker1

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

 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                 
       }
    }

答案 3 :(得分:0)

看看BackgroundWorker控件。在表单加载调用期间

backgroundWorker.RunWorkerAsync();

并覆盖事件DoWork以执行脏工作(从db加载数据)和ProgressChanged以更新进度条。在事件正文中(假设事件签名将是这样的):

 private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
   var worker = (BackgroundWorker)sender;
   // time consuming operation
   worker.ReportProgress(10, null);
   // ... another stuff
 }


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