Search code examples
c#wpfprogress-barbackgroundworkersystem.diagnostics

WPF ProgressBar - make the progress bar completed after the operation finished


I have a WPF form which runs a background operation with progress bar. but the problem is that;

when the operation is completed, the progress bar is still running. I mean it shows like the operation is in progress.

how can I stop that? here is my whole code;

System.ComponentModel.BackgroundWorker mWorker;

private void button1_Click(object sender, RoutedEventArgs e) {

    mWorker = new System.ComponentModel.BackgroundWorker();
    mWorker.DoWork +=new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
    mWorker.ProgressChanged +=new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
    mWorker.WorkerReportsProgress = true;
    mWorker.WorkerSupportsCancellation = true;
    mWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    mWorker.RunWorkerAsync();

    while (pbProcessing.Value != 100) {

        if (!mWorker.CancellationPending) {

            try {

                pbProcessing.Value = (pbProcessing.Value + 0.01) % 100;

            } catch (System.Exception ex) {

                // No action required
            }

        } else {

            MessageBox.Show(this, "Process cancelled", "Cancel Process", MessageBoxButton.OK);
            break;

        }

        System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
               new System.Threading.ThreadStart(delegate { }));

    }

}

private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {

    // Do your work here, its on seperate thread
    System.Threading.Thread.Sleep(10000);

}
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) {

    pbProcessing.Value = e.ProgressPercentage;

}
private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) {

    // Stop Progressbar updatation  
    Window1 w = new Window1();
    w.Browser.Navigate(new Uri("http://stackoverflow.com"));
    w.Show();

}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {

    if (mWorker != null) {

        if (mWorker.IsBusy) {
            mWorker.CancelAsync();
        }

    }

}

Solution

  • If you want to hide the progressbar after the work is done, set its Visibility property to Visibility.Hidden. If you just want to reset it to its initial state, set it's Value to 0 (or to pbProgressing.Minimum, if you changed that from its default value).


    As a side note, your code doesn't really make sense: Instead of continuously changing pbProcessing.Value in the button event handler (which is completely useless, since no UI updates are performed until the button event handler has completed), you should only change the value in ProgressChanged. I.e., your code should look something like this:

    System.ComponentModel.BackgroundWorker mWorker;
    
    private void button1_Click(object sender, RoutedEventArgs e) {
    
        mWorker = new System.ComponentModel.BackgroundWorker();
        mWorker.DoWork +=new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
        mWorker.ProgressChanged +=new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
        mWorker.WorkerReportsProgress = true;
        mWorker.WorkerSupportsCancellation = true;
        mWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        mWorker.RunWorkerAsync();
    
        // Don't do anything else here
    
    }
    
    private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
        for (int i = 1; i < 100; i++) {
            mWorker.ReportProgress(i);
    
            // Do some part of the work
            System.Threading.Thread.Sleep(100);
    
            // Check if the user wants to abort
            if (mWorker.CancellationPending) {
                e.Cancel = true;
                return;
            }
        }
    
        mWorker.ReportProgress(100);  // Done
    }
    
    private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) {
        pbProcessing.Value = e.ProgressPercentage;
    }
    
    private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) {
    
        // Stop Progressbar updatation  
        Window1 w = new Window1();
        w.Browser.Navigate(new Uri("http://stackoverflow.com"));
        w.Show();
    
        // Check the result
        if (e.Cancelled) {
            // show the message box that the task has been canceled
        }
    
        // Reset Progress bar
        pbProcessing.Value = 0;
    }
    
    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
        if (mWorker != null) {
            if (mWorker.IsBusy) {
                mWorker.CancelAsync();
            }
        }
    }