正确使用进度条

时间:2016-04-21 08:13:38

标签: c# progress-bar

这是我第一次在C#中使用进度条。 我的代码是复制一些文件,我想通过进度条显示进度。

我不喜欢我的代码是我必须通过所有文件来设置条形码的最大值...然后我再次通过相同的过程来复制文件。

我无法找到一种方法来确保在没有这样做的情况下在酒吧中取得流畅的进展。我首先要知道最大权利吗?或者有诀窍吗?

代码看起来像这样:

  • 设置最大值:

    private static void setProgressBar(List<Source> sources, List<Destination> destinations)
    {
        progress.Value = 0;
        progress.Maximum = 0;
    
        foreach (var source in sources)
        {
            progress.Maximum += System.IO.Directory.GetDirectories(source.directory, "*",
                SearchOption.AllDirectories).Count() * destinations.Count +
                System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories).Count() *
                destinations.Count;
        }
    
  • 复制文件:

    public static void CopyData(List<Source> sources, List<Destination> destinations, RichTextBox box, ProgressBar bar)
    {
        log = box;
        progress = bar;
        setProgressBar(sources, destinations);
    
        foreach (var source in sources)
        {
            foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*",
                SearchOption.AllDirectories))
            {
                foreach (var destination in destinations)
                {
                    logger(dirPath);
                    System.IO.Directory.CreateDirectory(dirPath.Replace(source.directory, destination.directory));
                }
            }
    
            foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories))
            {
                foreach (var destination in destinations)
                {
                    logger(newPath);
                    File.Copy(newPath, newPath.Replace(source.directory, destination.directory), true);
                }
            }
        }
    }
    
  • 增加进度条:

    private static void logger(string output)     {         log.Text + =&#34;复制:&#34; + output + System.Environment.NewLine;         log.SelectionStart = log.Text.Length;         log.ScrollToCaret();         progress.Increment(1);     }

所以我两次运行相同的代码......我不喜欢这样:)

1 个答案:

答案 0 :(得分:1)

我在这里看到两个错误:你从未在CopyData方法中设置进度条的值 第二个是:你的CopyData方法将导致你的UI冻结,直到方法完成(并且进度条将在那时从0跳到100%)。

您可以将CopyData方法放在BackgroundWorker中并调用ReportProgress并在ReportProgress事件中设置条形图的新值。

以下是如何完成的示例。而不是static void Main(..)调用工作人员从哪里开始你的CopyData方法

static void Main(string[] args)
{
    System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
    worker.ProgressChanged += Worker_ProgressChanged;
    worker.DoWork += Worker_DoWork;

    //Do work
    worker.RunWorkerAsync();
}

private static void Worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    //Get Values
    var source = null;
    var destinations = null;

    //CopyData Method
    setProgressBar(sources, destinations);
    foreach (var source in sources)
    {
        foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories))
        {
            foreach (var destination in destinations)
            {
                logger(dirPath);
                System.IO.Directory.CreateDirectory(dirPath.Replace(source.directory, destination.directory));
                //Increase Value by 1
                (sender as System.ComponentModel.BackgroundWorker).ReportProgress(1);
            }
        }

        foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories))
        {
            foreach (var destination in destinations)
            {
                logger(newPath);
                File.Copy(newPath, newPath.Replace(source.directory, destination.directory), true);
                //Increase Value by 1
                (sender as System.ComponentModel.BackgroundWorker).ReportProgress(1);
            }
        }
    }
}

private static void Worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
    if (e.ProgressPercentage == 1)
    {
        //If Value gets higher than Maximum it will cause an Exception
        if (progress.Value < progress.Maximum)
            progress.Value += 1;
    }
}

private static void setProgressBar(List sources, List destinations)
{
    progress.Value = 0;
    progress.Maximum = 0;
    foreach (var source in sources)
    {
        foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories))
        {
            //Simplified
            progress.Maximum += destinations.Count;
        }

        foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories))
        {
            //Simplified
            progress.Maximum += destinations.Count;
        }
    }
}