正确使用进度条
本文关键字: | 更新日期: 2024-10-25 04:54:08
这是我第一次在 C# 中使用进度条。我的代码正在复制一些文件,我想通过进度条显示进度。
我不喜欢我的代码的一点是,我必须遍历所有文件才能设置最大值......后来我再次经历相同的过程来复制文件。
我只是想不出一种方法来确保酒吧的流畅进步而不这样做。我首先必须知道最大值,对吗?还是有诡计?
代码如下所示:
设置最大值:
private static void setProgressBar(List<Source> sources, List<Destination> destinations) { progress.Value = 0; progress.Maximum = 0; foreach (var source in sources) { progress.Maximum += System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories).Count() * destinations.Count + System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories).Count() * destinations.Count; }
复制文件:
public static void CopyData(List<Source> sources, List<Destination> destinations, RichTextBox box, ProgressBar bar) { log = box; progress = bar; setProgressBar(sources, destinations); foreach (var source in sources) { foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories)) { foreach (var destination in destinations) { logger(dirPath); System.IO.Directory.CreateDirectory(dirPath.Replace(source.directory, destination.directory)); } } foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories)) { foreach (var destination in destinations) { logger(newPath); File.Copy(newPath, newPath.Replace(source.directory, destination.directory), true); } } } }
递增进度条:
私人静态空隙记录仪(字符串输出) { .log。文本 += "复制: " + 输出 + 系统.环境.新行; .log。选择开始 = 日志。文本长度; .log。ScrollToCaret(); 进展。增量(1); }
所以我运行相同的代码两次...我不喜欢这样:)
我在这里看到两个错误:您从未在 CopyData 方法中设置进度条的值第二个是:你的 CopyData 方法会导致你的 UI 冻结,直到方法完成(此时进度条将从 0 跳到 100%)。
您可以将 CopyData 方法放在 BackgroundWorker 中并调用 ReportProgress,并在 ReportProgress-event 中设置栏的新值。
下面是如何做到这一点的示例。而不是static void Main(..)
调用工作线程,您将从那里开始 CopyData 方法
static void Main(string[] args)
{
System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
worker.ProgressChanged += Worker_ProgressChanged;
worker.DoWork += Worker_DoWork;
//Do work
worker.RunWorkerAsync();
}
private static void Worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
//Get Values
var source = null;
var destinations = null;
//CopyData Method
setProgressBar(sources, destinations);
foreach (var source in sources)
{
foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories))
{
foreach (var destination in destinations)
{
logger(dirPath);
System.IO.Directory.CreateDirectory(dirPath.Replace(source.directory, destination.directory));
//Increase Value by 1
(sender as System.ComponentModel.BackgroundWorker).ReportProgress(1);
}
}
foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories))
{
foreach (var destination in destinations)
{
logger(newPath);
File.Copy(newPath, newPath.Replace(source.directory, destination.directory), true);
//Increase Value by 1
(sender as System.ComponentModel.BackgroundWorker).ReportProgress(1);
}
}
}
}
private static void Worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
if (e.ProgressPercentage == 1)
{
//If Value gets higher than Maximum it will cause an Exception
if (progress.Value < progress.Maximum)
progress.Value += 1;
}
}
private static void setProgressBar(List sources, List destinations)
{
progress.Value = 0;
progress.Maximum = 0;
foreach (var source in sources)
{
foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories))
{
//Simplified
progress.Maximum += destinations.Count;
}
foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories))
{
//Simplified
progress.Maximum += destinations.Count;
}
}
}