在表单加载上使用进度条
对不起,我的英语不好
我正在尝试在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将等待,直到数据读取进度完成,我只能看到一个完整的进度条和所有加载的数据。
我该怎么做才能解决这个问题?
谢谢
由于这是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; }
这是一个简单的模型,向您展示如何使用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)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 }
将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 } }
看看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; }