如何使用BackgroundWorker与自定义进度对话框(窗体与ProgressBar)
本文关键字:窗体 ProgressBar 对话框 何使用 BackgroundWorker 自定义 | 更新日期: 2023-09-27 18:12:38
我有一个加载文件的方法。有时它需要花费很多时间,所以我想向用户展示一个进度条窗口,通过它他可以最小化整个应用程序或取消进度。
我读了一堆关于后台工作人员和进度条的教程,但这些都没有涵盖的情况下,当进度条是在一些其他形式。我不知道什么时候我应该打开新的表单,以及如何访问那里的进度条。
到目前为止,我已经试过了:
MainForm:
private void addFolderToolStripMenuItem_Click(object sender, EventArgs e)
{
ctlFolderSelectDialog dlg = new ctlFolderSelectDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
BackgroundWorker.RunWorkerAsync(dlg); // to pass some variables from ctlFolderSelectDialog
}
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
Form_Dialogs.ProgressDialog progressDialog = new Form_Dialogs.ProgressDialog();
progressDialog.ShowDialog(); // open the progress dialog window
myClass.loadFiles((ctlFolderSelectDialog)e.Argument); // THE WORK
progressDialog.Close(); // close the progress window - in here?
}
myClass:
public void loadFiles(ctlFolderSelectDialog dlg)
{
...
files.Count() // somehow report this preliminary number of files to ProgressBar window - to set ProgressBar1.Maximum value
...
foreach (file in files)
{
loadFile();
... // here I should somehow udpate the progressBar on the other window - performStep()
}
}
ProgressDialog:
private void ProgressDialog_Load(object sender, EventArgs e)
{
progressBar1.Value = 0;
progressBar1.Maximum = 100; // how to get this value from myClass function? Pass in ProgressDialog contructor?
progressBar1.Step = 1;
}
public void UpdateProgress(int progress)
{
progressBar1.PerformStep();
}
BackgroundWorker
支持通过ProgressChanged
事件进行进度更新。
在loadFiles()
方法中需要计算%的进度,在foreach
循环中调用backgroundWorker.ReportProgress(percentage)
。这将引发ProgressChanged
事件,您可以从中获得事件参数e.ProgressPercentage
。[你需要在loadFiles()
方法中引用BackgroundWorker
]
在ProgressDialog
表单中,您需要注册此事件。您可以在构造函数中传递BackgroundWorker
,例如:
public void ProgressDialog(BackgroundWorker worker)
{
worker.ProgressChanged += ProgressDialog_ProgressChanged;
}
private void ProgressDialog_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
UpdateProgressBar(e.ProgressPercentage);
}
和主要形式:
private void addFolderToolStripMenuItem_Click(object sender, EventArgs e)
{
ctlFolderSelectDialog dlg = new ctlFolderSelectDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
BackgroundWorker.RunWorkerAsync(dlg); // to pass some variables fromctlFolderSelectDialog
Form_Dialogs.ProgressDialog progressDialog =
new Form_Dialogs.ProgressDialog(BackgroundWorker); // Pass the BackgroundWorker instance
progressDialog.ShowDialog(); // open the progress dialog window
// No need to explicitly close it. A dialog form is destroyed when closed by the user.
}
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
myClass.loadFiles((ctlFolderSelectDialog)e.Argument); // THE WORK
}