Mr. Toast
Mr. Toast

Reputation: 951

Proper use of progress bar

It's my first time using progress bars in C#. My code is copying some files and I would like to display the progress via a progress bar.

The thing I don't like about my code is that I have to go through all files to set the maximum of the bar... and later I go through that same process again to copy the files.

I just can't figure out a way to ensure a fluent progress in the bar without doeing that. I first have to know the max right? Or is there a trick?

Code looks like that:

So I'm running the same code twice... and I don't like that :)

Upvotes: 2

Views: 990

Answers (1)

Marcel B
Marcel B

Reputation: 518

I see two Errors in here: you never set your progressbar's value in the CopyData method and the second one is: your CopyData method will cause your UI to freeze until the method is done (and the progressbar will jump from 0 to 100% at that time).

You can put your CopyData method in a BackgroundWorker and call ReportProgressand set the new Value of your bar in the ReportProgress-event.

Here is an example of how it could be done. Instead of static void Main(..) call the worker from where you would start your CopyData-method

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

Upvotes: 1

Related Questions