我对编程非常陌生,到目前为止表现相当不错。但是进度条仍然让我困惑。不幸的是,网络上有许多不同的例子让我从中获取任何东西。有些人说使用后台工作人员有些不这样做等等。下面我知道我认为应该工作但是没有。在将文件从一个文件夹复制到另一个文件夹时,它只是一个进度条。任何帮助表示赞赏。
感谢。
private void btnCopyFiles_Click(object sender, EventArgs e)
{
string folder1 = @"c:\folder1\";
string folder2 = @"c:\folder2\";
DirectoryInfo di = new DirectoryInfo(folder1);
FileInfo[] filelist = di.GetFiles("*.*");
int count = di.GetFiles("*.*").Length;
this.progressBar1 = new System.Windows.Forms.ProgressBar();
progressBar1.Maximum = count;
progressBar1.Minimum = 0;
progressBar1.Step = 1;
foreach (FileInfo file in filelist)
{
try
{
this.Cursor = Cursors.WaitCursor;
File.Copy(folder1 + @"\" + file.Name, folder2 + @"\" + file.Name, true);
progressBar1.PerformStep();
this.Cursor = Cursors.Default;
}
catch (Exception error)
{
MessageBox.Show("Error: " + error);
}
}
}
答案 0 :(得分:4)
我假设您正在使用Visual Studio并通过将其拖动到表单添加了ProgressBar控件。如果这是正确的,那么以下行可能是问题:
this.progressBar1 = new System.Windows.Forms.ProgressBar();
通过重新创建控件,您将丢失其与表单的链接。只需删除或评论该行并再次尝试。
答案 1 :(得分:2)
总体而言,问题是您的代码继续执行,不允许表单根据需要重新绘制自己。您最好,最快的路线是使用BackgroundWorker实际执行操作,使用其事件来更新进度。这样做,进度条的更新在UI线程上完成,UI更新,你的文件操作在幕后继续。
答案 2 :(得分:2)
首先,创建一个结构来保存BackgroundWorker的参数,该结构将在DoWorkEventArgs中传递。
public struct CopyStruct
{
public string sourceDir;
public string destDir;
}
然后,做这样的事情:
private void btnCopyFiles_Click(object sender, EventArgs e)
{
InitializeBackgroundWorker();
CopyStruct copyStruct = new CopyStruct
{
sourceDir = @"C:\folder1\",
destDir = @"C:\folder2\"
};
backgroundWorker.RunWorkerAsync(copyStruct);
}
private void InitializeBackgroundWorker()
{
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// do something when finished
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker) sender;
CopyStruct copyStruct = (CopyStruct) e.Argument;
DirectoryInfo di = new DirectoryInfo(copyStruct.sourceDir);
FileInfo[] filelist = di.GetFiles("*.*");
int numFiles = filelist.Length;
for (int i = 0; i < numFiles; i++)
{
FileInfo file = filelist[i];
File.Copy(Path.Combine(copyStruct.sourceDir, file.Name), Path.Combine(copyStruct.destDir, file.Name), true);
// This line updates the progress bar
worker.ReportProgress((int) ((float) i/numFiles*100));
}
}
这几乎不包含错误检查,所以你必须添加它,但它适用于我系统上的一些测试目录。
答案 3 :(得分:1)
对于要在用户界面中更新的进度条,正在处理某事的进程必须在另一个线程上执行(否则它会阻止UI线程,并且不会更新UI)。 BackgroundWorker是这样做的好选择。
在后台工作程序的DoWork事件中执行文件复制循环,并调用BackgroundWorker.ReportProgress方法以报告进度。在ProgressChanged事件的事件处理程序中,您可以在ProgressBar控件中设置值。您可以通过调用BackgroundWorker组件上的RunWorkerAsync方法来启动该过程。
答案 4 :(得分:1)
由于您不熟悉编程,所以
添加
Application.DoEvents();
后
progressBar1.PerformStep();
这应该让您的应用程序正常运行。您最终希望将复制过程移动到线程/后台工作程序。但是不知道你的能力,Application.DoEvents()可能是最容易修复的,但不是首选修复。
答案 5 :(得分:0)
您是否尝试过progressbar1.Increment(x)其中x是传输的文件数?