tags:

views:

161

answers:

6
+1  Q: 

Progress Bar help

Hello, I'm very much new to programming and have been doing fairly well so far. But progress bars still confuse me. The web unfortunately has to many differing examples for me to get anything out of them. Some say to use background worker some don't, etc. Below I have what I THINK should work but doesn't. Its just supposed to she a progress bar when copying file from one folder to another. Any help is appreciated.

Thanks.

        private void btnCopyFiles_Click(object sender, EventArgs e)
    {
        string folder1 = @"c:\folder1\";
        string folder2 = @"c:\folder2\";

        DirectoryInfo di = new DirectoryInfo(folder1);
        FileInfo[] filelist = di.GetFiles("*.*");
        int count = di.GetFiles("*.*").Length;

        this.progressBar1 = new System.Windows.Forms.ProgressBar();
        progressBar1.Maximum = count;
        progressBar1.Minimum = 0;
        progressBar1.Step = 1;

        foreach (FileInfo file in filelist)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                File.Copy(folder1 + @"\" + file.Name, folder2 + @"\" + file.Name, true);
                progressBar1.PerformStep();
                this.Cursor = Cursors.Default;
            }
            catch (Exception error)
            {
                MessageBox.Show("Error: " + error);
            }
        }
    }
+4  A: 

I'm assuming that you are using Visual Studio and have added the ProgressBar control by dragging it to the form. If this is correct, then following line, may be the problem:

this.progressBar1 = new System.Windows.Forms.ProgressBar();

By recreating the control, you are loosing its link to the form. Just remove or comment that line and try it again.

ichiban
Awesome thanks! That works. Somewhere along the way I thought I had to have that in there. But works great. Thanks again.
JimDel
Is there a reason why you accepted my answer and then un-accepted it?
ichiban
ah. Good eye. I didn't see that.
Chris Persichetti
sorry, didnt know i did that. it should be the answer again.
JimDel
A: 

have you tried progressbar1.Increment(x) where x is the number of files transferred?

miguel
The code already has progressBar1.PerformStep() which takes care of that.
ichiban
+2  A: 

Overall the issue is that your code continues to execute not allowing the form to re-draw itself as it needs to. Your best, and fastest route is to use a BackgroundWorker to actually perform your operation, using its events to update the progress. Doing this, the update to the progress bar is done on the UI thread, and the UI updates, your file operations go on behind the scenes.

Mitchel Sellers
ichibans answer solvled my problem. But I will look more into the backgroundworker way as well. Thanks :)
JimDel
+1  A: 

For the progress bar to be updated in your user interface, the process that is working on something must execute on another thread (otherwise it blocks the UI thread, and the UI will not be updated). The BackgroundWorker is a good candidate for doing this.

Perform your file copy loop in the DoWork event of the background worker, and call the BackgroundWorker.ReportProgress method to, well, report progress. In the event handler for the ProgressChanged event you can set the value in your ProgressBar control. You start the process by calling the RunWorkerAsync method on the BackgroundWorker component.

Fredrik Mörk
+1  A: 

Since you are new to programming start with this.

Add

    Application.DoEvents();

after

    progressBar1.PerformStep();

This should get your application working for now. You'll eventually want to move your copy process to a thread/Background worker. But not knowing your abilities, the Application.DoEvents() is probably the easiest fix, but not the prefered fix.

Chris Persichetti
+1  A: 

First, create a struct to hold arguments to the BackgroundWorker, which will be passed in DoWorkEventArgs.

public struct CopyStruct
{
    public string sourceDir;
    public string destDir;
}

Then, do something like this:

private void btnCopyFiles_Click(object sender, EventArgs e)
{
    InitializeBackgroundWorker();

    CopyStruct copyStruct = new CopyStruct
    {
        sourceDir = @"C:\folder1\",
        destDir = @"C:\folder2\"
    };

    backgroundWorker.RunWorkerAsync(copyStruct);
}

private void InitializeBackgroundWorker()
{
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.DoWork += backgroundWorker_DoWork;
    backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
    backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
}

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

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // do something when finished
}

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker) sender;
    CopyStruct copyStruct = (CopyStruct) e.Argument;

    DirectoryInfo di = new DirectoryInfo(copyStruct.sourceDir);
    FileInfo[] filelist = di.GetFiles("*.*");

    int numFiles = filelist.Length;

    for (int i = 0; i < numFiles; i++)
    {
        FileInfo file = filelist[i];

        File.Copy(Path.Combine(copyStruct.sourceDir, file.Name), Path.Combine(copyStruct.destDir, file.Name), true);

        // This line updates the progress bar
        worker.ReportProgress((int) ((float) i/numFiles*100));
    }
}

This contains almost no error checking, so you'll have to add that, but it works with a few test directories on my system.

Chris Doggett
Wow thats a lot of work on your part! Thank you so much! Now I have some experimenting ahead of me.
JimDel
Thanks. If what you have works for you, you don't need a BackgroundWorker. I only needed one because I also had a label that was updated with something like "3209/9000 (35%)". Without the BackgroundWorker, the label would never get updated, but it works fine in the backgroundWorker_ProgressChanged function.
Chris Doggett