2

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?

4

4 回答 4

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 changed 事件将触发以安全地更新 UI:

private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
     progressBar.Value = e.ProgressPercentage;
}
于 2013-06-18T09:08:16.270 回答
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                 
    }
}
于 2013-06-18T09:17:25.550 回答
2

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

首先在您的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
}
于 2013-06-18T09:08:51.873 回答
0

看看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;
}
于 2013-06-18T09:10:05.560 回答