抱歉我的英文不好
我正在尝试在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会等待,直到数据读取进度完成,我只能看到一个完整的进度条和所有加载的数据。
我该怎么做才能解决这个问题?
由于
答案 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;
}