我有一个加载文件的方法。有时需要花费很多时间,所以我想向用户显示一个progressBar窗口,用它可以最小化整个应用程序或取消进度。
我已经阅读了一些关于BackgroundWorkers和ProgressBars的教程,但是当ProgressBar位于其他Form时,这些教程都没有涵盖这个场景。我不知道我应该何时打开新表单以及如何访问那里的进度条。
到目前为止,我已经尝试过:
的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();
}
答案 0 :(得分:1)
BackgroundWorker
通过ProgressChanged
事件支持进度更新。
在loadFiles()
方法中,您需要在foreach
循环调用backgroundWorker.ReportProgress(percentage)
内计算%的进度。这将引发ProgressChanged
事件,您可以在事件参数e.ProgressPercentage
中获取该事件。 [您需要引用BackgroundWorker
方法中的loadFiles()
在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
}