C# 如何使progressbar显示正在复制的目录的进度

C# 如何使progressbar显示正在复制的目录的进度,c#,winforms,C#,Winforms,我有一段代码,可以将一个文件夹复制到另一个目录。我想实现一个进度条,以便用户可以看到正在复制的文件的进度。我试过一些方法,但就是不能成功 这是我认为可以实现上面所说的代码,但是进度条没有任何进展,这就是为什么文件夹实际上被复制的原因 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO

我有一段代码,可以将一个文件夹复制到另一个目录。我想实现一个进度条,以便用户可以看到正在复制的文件的进度。我试过一些方法,但就是不能成功

这是我认为可以实现上面所说的代码,但是进度条没有任何进展,这就是为什么文件夹实际上被复制的原因

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


但是,它确实复制了文件

您应该将复制过程置于一个状态,并从_bgwcopyooperation_ProgressChanged事件中刷新进度栏。 因为您正在GUI线程中处理复制操作,所以会阻止控件刷新

试试这样的。您仍然需要对此进行一些修改,以便将参数传递给_bgwcopyooperation_DoWork事件


BackgroundWorker当然是最好的方法,它将把所有繁重的拷贝发送到一个单独的线程中,而不是让GUI线程忙于简单的拷贝

…但是,如果要复制小文件夹,可以尝试使用进度条上的
刷新功能:

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;
        }
    }
}
使用系统;
使用系统线程;
使用System.Windows.Forms;
名称空间ProgressBat
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
按钮1.启用=错误;
progressBar1.值=0;
对于(int i=0;i<100;i++)
{
progressBar1.值=i;
progressBar1.Refresh();
睡眠(50);
}
按钮1.启用=真;
}
}
}
该示例将使进度条正确移动。

这是对代码的一行修复

我没有看到任何线程或后台工作人员?像这样的事情都发生在主线程上…检查进度条的最小值和最大值是否设置为0和0100@User965207进度条的最小值和最大值确实设置为0,并且100I查看进度条,但我还在另一个问题上苦苦挣扎:在
\u bgwcopyooperation\u DoWork
中,DirectoryCopy
被调用。但因为你让它成为一个后台工作人员,DirectoryCopy已经不存在了。如何在BackgroundWorker内部调用该函数表单?这就是后台工作人员的工作方式。这不仅仅是对函数的重命名。我的回答只是你的一种方法。阅读我答案中的链接。用类似于bgwcopyooperation.RunWorkerAsync(参数)的东西启动Backgroundworker,因此我更改了
DirectoryCopy(subdir.FullName、temppath、copySubders)带有
\u bgwcopyooperation.RunWorkerAsync(subdir.FullName、temppath、copySubDirs)
但现在它给了我以下错误:
方法'RunWorkerAsync'不重载3个参数
必须将多个参数包装成一个参数。例如,作为数组或自己的类/结构。RunWorkerAsync(对象参数),这是我现在的代码,但现在它不会更改进度条,也不会复制文件夹
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;
        }
    }
}