正确使用进度条
Proper use of progress bar
这是我第一次在 C# 中使用进度条。
我的代码正在复制一些文件,我想通过进度条显示进度。
我不喜欢我的代码的一点是我必须遍历所有文件来设置 bar 的最大值...然后我再次经历相同的过程来复制文件。
我只是想不出一种方法来确保在不这样做的情况下在酒吧里顺利进行。我首先必须知道最大值对吗?或者有什么技巧?
代码看起来像这样:
正在设置最大值:
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);
}
}
}
}
增加进度条:
private static void logger(字符串输出)
{
log.Text += "Copy: " + 输出 + System.Environment.NewLine;
log.SelectionStart = log.Text.长度;
log.ScrollToCaret();
progress.Increment(1);
}
所以我 运行 两次相同的代码...我不喜欢那样:)
我在这里看到两个错误:您从未在 CopyData 方法中设置进度条的值
第二个是:您的 CopyData 方法将导致您的 UI 冻结,直到该方法完成(此时进度条将从 0 跳到 100%)。
您可以将 CopyData 方法放在 BackgroundWorker 中并调用 ReportProgress 并在 ReportProgress 事件中设置栏的新值。
这是一个如何完成的例子。而不是 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;
}
}
}
这是我第一次在 C# 中使用进度条。 我的代码正在复制一些文件,我想通过进度条显示进度。
我不喜欢我的代码的一点是我必须遍历所有文件来设置 bar 的最大值...然后我再次经历相同的过程来复制文件。
我只是想不出一种方法来确保在不这样做的情况下在酒吧里顺利进行。我首先必须知道最大值对吗?或者有什么技巧?
代码看起来像这样:
正在设置最大值:
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); } } } }
增加进度条:
private static void logger(字符串输出) { log.Text += "Copy: " + 输出 + System.Environment.NewLine; log.SelectionStart = log.Text.长度; log.ScrollToCaret(); progress.Increment(1); }
所以我 运行 两次相同的代码...我不喜欢那样:)
我在这里看到两个错误:您从未在 CopyData 方法中设置进度条的值 第二个是:您的 CopyData 方法将导致您的 UI 冻结,直到该方法完成(此时进度条将从 0 跳到 100%)。
您可以将 CopyData 方法放在 BackgroundWorker 中并调用 ReportProgress 并在 ReportProgress 事件中设置栏的新值。
这是一个如何完成的例子。而不是 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;
}
}
}