【问题标题】:Copying Files From One Directory to Another With Progress bar C# WPF使用进度条 C# WPF 将文件从一个目录复制到另一个目录
【发布时间】:2022-01-21 23:11:49
【问题描述】:

我正在使用以下代码将文件从一个目录复制到另一个目录

private void CopyFilesRecursively(string serverDirectorty, string localDirectory)
    {
        serverDirectorty = settings["baseDocPathSource"] as string;
        localDirectory = settings["baseDocPath"] as string;

        //Now Create all of the directories
        foreach (string dirPath in Directory.GetDirectories(serverDirectorty, "*", SearchOption.AllDirectories))
        {
            Directory.CreateDirectory(dirPath.Replace(serverDirectorty, localDirectory));
        }

        //Copy all the files & Replaces any files with the same name
        foreach (string newPath in Directory.GetFiles(serverDirectorty, "*.*", SearchOption.AllDirectories))
        {
            File.Copy(newPath, newPath.Replace(serverDirectorty, localDirectory), true);
        }
    }

我想将进度条集成到我的代码中,即,当我单击复制按钮时,我想显示进度条从 0 移动到 100,当文件复制完成时,我想隐藏进度条。

下面是我的 XML 文件

    <Grid>
    <ProgressBar Visibility="Hidden" Name="pbCopy" HorizontalAlignment="Left" Height="65" Margin="127,151,0,0" VerticalAlignment="Top" Width="485"/>
    <Button Content="Copy Files" HorizontalAlignment="Left" Margin="283,253,0,0" VerticalAlignment="Top" Width="164" Height="66"/>

</Grid>

我想最初从我的表单中隐藏进度条,并希望在单击按钮后设置可见性“可见”

【问题讨论】:

    标签: c# wpf progress-bar backgroundworker file-copying


    【解决方案1】:

    尝试使用Progress 类。将其传递给您的方法。

    private void CopyFilesRecursively(string serverDirectorty, string localDirectory, IProgress<double> progress)
    {
        serverDirectorty = settings["baseDocPathSource"] as string;
        localDirectory = settings["baseDocPath"] as string;
    
        //Now Create all of the directories
        foreach (string dirPath in Directory.GetDirectories(serverDirectorty, "*", SearchOption.AllDirectories))
        {
           Directory.CreateDirectory(dirPath.Replace(serverDirectorty, localDirectory));
        }
    
        //Copy all the files & Replaces any files with the same name
        var files = Directory.GetFiles(serverDirectorty, "*.*", SearchOption.AllDirectories);
    
        double processed = 0;
        //Reset progress value to 0.
        progress?.Report(0);
                
        foreach (string newPath in files)
        {
            File.Copy(newPath, newPath.Replace(serverDirectorty, localDirectory), true);
            //Report in percentage 1-100%. If you have a ton of files, you should reduce the number of calling progress?.Report() e.g. using dividing by modulo.
            progress?.Report((++processed / files.Length) * 100);
        }
                
        //If files weren't found.
        progress?.Report(100);
    }
    

    【讨论】:

    • 在调用函数时我必须提供什么正在进行的参数?我不习惯 Progress 类。
    • 然后将 IProgress 替换为 Func 但这不是很好的解决方案,尤其是对于 WPF。
    【解决方案2】:

    在 XAML 标记中为 ProgressBar 命名:

    <ProgressBar x:Name="pb" ... />
    

    ...并在您的方法中设置其属性。像这样的:

    private void CopyFilesRecursively(string serverDirectorty, string localDirectory)
    {
        serverDirectorty = settings["baseDocPathSource"] as string;
        localDirectory = settings["baseDocPath"] as string;
    
        //Now Create all of the directories
        foreach (string dirPath in Directory.GetDirectories(serverDirectorty, "*", SearchOption.AllDirectories))
        {
            Directory.CreateDirectory(dirPath.Replace(serverDirectorty, localDirectory));
        }
    
        //Copy all the files & Replaces any files with the same name
        string[] files = Directory.GetFiles(serverDirectorty, "*.*", SearchOption.AllDirectories);
        pb.Dispatcher.Invoke(() =>
        {
            pb.Visibility = Visibility.Visible;
            pb.Maximum = files.Length;
            pb.Value = 0;
        });
        for (int i = 0; i < files.Length; i++)
        {
            string newPath = files[i];
            File.Copy(newPath, newPath.Replace(serverDirectorty, localDirectory), true);
            pb.Dispatcher.Invoke(() => pb.Value += i + 1);
        }
        pb.Dispatcher.Invoke(() => pb.Visibility = Visibility.Collapsed);
    }
    

    还要确保您在后台线程上运行您的复制方法:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Task.Run(() => CopyFilesRecursively("...", "..."));
    }
    

    【讨论】:

    • 你指的是哪里的进度条“” pb。我在 XML 中更改了名称,但“pb”仍然存在错误错误:上下文中不存在名称“pn”
    • 它被称为“pb”而不是“pn”。请参阅我的示例中 string[] files ... 下方的代码。
    • pb.Dispatcher.Invoke(() => 我在这里遇到错误,因为它没有在 xml 中找到 pb,尽管我给它起了名字“x:Name="pb"”
    • 那么您在 XAML 中的哪个位置定义了 ProgressBar?该方法定义在哪个类中?
    猜你喜欢
    • 2020-06-22
    • 2012-02-15
    • 2021-02-15
    • 1970-01-01
    • 2017-11-18
    • 2013-06-01
    • 2014-08-12
    • 2013-10-24
    相关资源
    最近更新 更多