【问题标题】:Using a Progress bar on Form Load在表单加载上使用进度条
【发布时间】:2013-06-18 09:00:23
【问题描述】:

我正在尝试在 C# 中设计一个 WinForms 控件,该控件将在加载时从数据库中获取一些数据。

我想用进度条来显示进度。

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

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

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

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

【问题讨论】:

标签: c# winforms progress-bar


【解决方案1】:

由于这是 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 changed 事件以安全地更新 UI:

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

【讨论】:

    【解决方案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】:

      这是一个简单的模型,向您展示如何与后台工作人员一起工作:

      首先在您的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
      }
      

      【讨论】:

        【解决方案4】:

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

        backgroundWorker.RunWorkerAsync();
        

        并覆盖事件DoWork 来做脏活(从数据库加载数据)和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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-29
          • 1970-01-01
          • 1970-01-01
          • 2013-04-18
          相关资源
          最近更新 更多