如何使进度条显示要复制的目录的进度

时间:2019-04-14 18:32:19

标签: c# winforms

我有一段代码,可以将一个文件夹复制到另一个目录。我想实现一个进度条,以便用户可以看到正在复制的文件的进度。我已经尝试了一些方法,但是我无法使其正常工作。

这是我认为可以执行上述操作的代码,但是进度条没有取得任何的进展,这是为什么实际上要复制文件夹的原因。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace intChanger
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        string Dirr;
        string Dirr2;
        int no = 0;
        int Count = 0;
        int Count2 = 0;
        private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
        {
            if (no == 0)
            {
                no = 1;
                Dirr = sourceDirName;
                Dirr2 = destDirName;
                Count = Directory.GetFiles(Dirr, "*.*", SearchOption.AllDirectories).Length;
                Count = 100 / Count;
            }

            // Get the subdirectories for the specified directory.
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);

            if (!dir.Exists)
            {
                throw new DirectoryNotFoundException(
                    "Source directory does not exist or could not be found: "
                + sourceDirName);
            }

            DirectoryInfo[] dirs = dir.GetDirectories();
            // If the destination directory doesn't exist, create it.
            if (!Directory.Exists(destDirName))
            {
                Directory.CreateDirectory(destDirName);
            }

            // Get the files in the directory and copy them to the new location.
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                string temppath = Path.Combine(destDirName, file.Name);
                file.CopyTo(temppath, false);
                Count2 = Count2 + 1;
                progressBar1.Value = Count2 * Count; 
            }

            // If copying subdirectories, copy them and their contents to new location.
            if (copySubDirs)
            {
                foreach (DirectoryInfo subdir in dirs)
                {
                    string temppath = Path.Combine(destDirName, subdir.Name);
                    DirectoryCopy(subdir.FullName, temppath, copySubDirs);
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            DirectoryCopy(@"C:\Users\Stefan\Downloads\Portable Python 2.7.15 Basic (x64)\Portable Python 2.7.15 x64", @"C:\Users\Stefan\Documents\Backuppers_Backups\Portable Python 2.7.15 x64", true);
            MessageBox.Show("Done coppieng", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}

我希望进度条缓慢上升,但不会:保持为0

但是实际上确实会复制文件

2 个答案:

答案 0 :(得分:3)

您应将复制过程放在BackgroundWorker中,并从 _bgwCopyOperation_ProgressChanged 事件刷新进度条。 由于您正在GUI线程中处理复制操作,因此将阻止刷新控件。

尝试类似这样的方法。您仍然需要对其进行一些修改,以将参数传递给 _bgwCopyOperation_DoWork 事件。

private void _bgwCopyOperation_DoWork(object sender, DoWorkEventArgs e)
{
    if (no == 0)
    {
        no = 1;
        Dirr = sourceDirName;
        Dirr2 = destDirName;
        Count = Directory.GetFiles(Dirr, "*.*", SearchOption.AllDirectories).Length;
        Count = 100 / Count;
    }    

    // Get the subdirectories for the specified directory.
    DirectoryInfo dir = new DirectoryInfo(sourceDirName);

    if (!dir.Exists)
    {
        throw new DirectoryNotFoundException(
            "Source directory does not exist or could not be found: "
        + sourceDirName);
    }    

    DirectoryInfo[] dirs = dir.GetDirectories();
    // If the destination directory doesn't exist, create it.
    if (!Directory.Exists(destDirName))
    {
        Directory.CreateDirectory(destDirName);
    }

    // Get the files in the directory and copy them to the new location.
    FileInfo[] files = dir.GetFiles();
    foreach (FileInfo file in files)
    {
        string temppath = Path.Combine(destDirName, file.Name);
        file.CopyTo(temppath, false);
        Count2 = Count2 + 1;

        //Update progressbar here
        _bgwCopyOperation.ReportProgress(Count2 * Count);
    }

    // If copying subdirectories, copy them and their contents to new location.
    if (copySubDirs)
    {
        foreach (DirectoryInfo subdir in dirs)
        {
            string temppath = Path.Combine(destDirName, subdir.Name);
            DirectoryCopy(subdir.FullName, temppath, copySubDirs);
        }
    }
}


private void _bgwCopyOperation_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

答案 1 :(得分:0)

BackgroundWorker当然是最好的方法,它将把所有繁重的副本发送到单独的线程中,而不会使GUI线程忙于简单的副本。

...但是如果您要复制小文件夹,则可以尝试使用进度条上的Refresh功能:

using System;
using System.Threading;
using System.Windows.Forms;

namespace ProgressBat
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            progressBar1.Value = 0;
            for (int i = 0; i < 100; i++)
            {
                progressBar1.Value = i;
                progressBar1.Refresh();
                Thread.Sleep(50);
            }
            button1.Enabled = true;
        }
    }
}

该示例将使进度条正确移动。
这是对代码的单行修复