进度条帮助

时间:2009-05-21 21:39:49

标签: c# .net winforms

我对编程非常陌生,到目前为止表现相当不错。但是进度条仍然让我困惑。不幸的是,网络上有许多不同的例子让我从中获取任何东西。有些人说使用后台工作人员有些不这样做等等。下面我知道我认为应该工作但是没有。在将文件从一个文件夹复制到另一个文件夹时,它只是一个进度条。任何帮助表示赞赏。

感谢。

        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);
            }
        }
    }

6 个答案:

答案 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是传输的文件数?