I want to display a progress bar while doing some work, but that would hang the UI and the progress bar won\'t update.
I have a WinForm ProgressForm with a Pro
Re: Your edit. You need a BackgroundWorker or Thread to do the work, but it must call ReportProgress() periodically to tell the UI thread what it is doing. DotNet can't magically work out how much of the work you have done, so you have to tell it (a) what the maximum progress amount you will reach is, and then (b) about 100 or so times during the process, tell it which amount you are up to. (If you report progress fewer than 100 times, the progess bar will jump in large steps. If you report more than 100 times, you will just be wasting time trying to report a finer detail than the progress bar will helpfully display)
If your UI thread can happily continue while the background worker is running, then your work is done.
However, realistically, in most situations where the progress indication needs to be running, your UI needs to be very careful to avoid a re-entrant call. e.g. If you are running a progress display while exporting data, you don't want to allow the user to start exporting data again while the export is in progress.
You can handle this in two ways:
The export operation checks to see if the background worker is running, and disabled the export option while it is already importing. This will allow the user to do anything at all in your program except exporting - this could still be dangerous if the user could (for example) edit the data that is being exported.
Run the progress bar as a "modal" display so that your program reamins "alive" during the export, but the user can't actually do anything (other than cancel) until the export completes. DotNet is rubbish at supporting this, even though it's the most common approach. In this case, you need to put the UI thread into a busy wait loop where it calls Application.DoEvents() to keep message handling running (so the progress bar will work), but you need to add a MessageFilter that only allows your application to respond to "safe" events (e.g. it would allow Paint events so your application windows continue to redraw, but it would filter out mouse and keyboard messages so that the user can't actually do anything in the proigram while the export is in progress. There are also a couple of sneaky messages you'll need to pass through to allow the window to work as normal, and figuring these out will take a few minutes - I have a list of them at work, but don't have them to hand here I'm afraid. It's all the obvious ones like NCHITTEST plus a sneaky .net one (evilly in the WM_USER range) which is vital to get this working).
The last "gotcha" with the awful dotNet progress bar is that when you finish your operation and close the progress bar you'll find that it usually exits when reporting a value like "80%". Even if you force it to 100% and then wait for about half a second, it still may not reach 100%. Arrrgh! The solution is to set the progress to 100%, then to 99%, and then back to 100% - when the progress bar is told to move forwards, it animates slowly towards the target value. But if you tell it to go "backwards", it jumps immediately to that position. So by reversing it momentarily at the end, you can get it to actually show the value you asked it to show.