I have a WinForms application, and wanted to add some nice WPF controls, one of them being an 'indeterminate' progress bar.. which just animates nicely until I tell it to stop.
I have done this, and was racking my brains as to why it wasn't animating (changing the value of the progress bar).
I eventually tried showing my form (containing the ElementHost) modally, and hey presto, it animates, but I want to show the form non-modally, as I want to continue processing behind the scenes.
Is there some kind of setting that tells the ElementHost window to continue 'animating'?
Thanks
Rich.
There are many ways to do this , the simplest one is to use a backgroundworker for the lengthy task. The Backgroundworker has an event to report progress. Handle this event and in the handler change your progressbar's value. Just having an animation in the main thread while still doing work on the main thread will not work right ...
One other aproach you may try (though is not what I would recommend for a healty app) is to implement a DoEvents function and call it in the main thread when you want the progress bar to get updated ... Here is the link for the DoEvents implementation:
MSDN DoEvents sugestion
I would Strongly recommend the first approach though
As I mention in my comment above, the solution is to run the processing in a separte thread, which allows the .net Main GUI thread do its stuff, and animate the progress bar.
Related
Im creating a c# windows form and ive come accross a problem.
When the window opens I am wanting to run a bit of code which can make the front console appear to freeze. The code runs fine but I want to show the status of the program in the status strip at the bottom of the page. I am running the code in the action Form.Shown. However the code does not update the status bar until everything is shown. I can change the label no problem.
How would I go about loading the window and then running the code and updating the status bar (like a background task)?
What areas would I need to look at to get this information?
You could use a BackgroundWorker to do this
Set the WorkerReportsProgress property to true and in the DoWork eventhandler raise the ReportProgress event
in the eventhandler for the ProgressChanged place your logic to update your progresbar
there is a example on msdn
You can use Multithreading to avoid freezing the forms. It means, you separate your form and the code (that you want to run in parallel) in different threads so that the form doesn't wait for the code completes. You can monitor the progress of the code via events.
I have a method called GetAllRecords() that will return a datatable of 200K records. When I checked it took about 5 seconds to load data to the datagrid and window froze.
DataTable dt = Records.GetAllRecords();
I know I have to use Background worker controls and it's three events, but I cannot figureout how to use them properly. For instance, the progress bar must show real progress not a fake one. I could slow the progress bar using sleep() of the thread class but it would be a fake progress bar.
Could any one here please give me step by step instructions on how to create a real progress bar on my windows form?
Before .NET 2.0 there was not Background worker control, in those days how programmer wrote real progress bars?
thanks
If you do a search of the site, as well as Google, you'll see that there are several attempts at doing this:
SO Link
MSDN Link
These solutions basically update the progress bar after you add each row to the grid, though if you're trying to show progress for an actual database call I don't think you'll be able to be very accurate on that.
I think the main problem you'll have is that you won't have event hooks to let you know exactly where the time-consuming part of the binding comes into play. I'm assuming that it takes 5 seconds once you bind the data to the grid and that you're not counting the load time of actually pulling down the records.
Pre-BackgroundWorker
The BackgroundWorker class is basically just a convenience to you handling the threading yourself and invoking any progress back to the UI thread for you. You would have to spawn your own thread, and call BeginInvoke on your control once work is done to apply the data to the UI thread, since you can't make changes to the UI on any thread but the main one.
For the basics on how to implement a BackgroundWorker and a ProgressBar you can consult the examples given in the MSDN pages for ProgressBar and BackgroundWorker
As for actually making the percentage completed-property of your ProgressBar make sense, the key lies in finding a meaningful value to use as the argument for BackgroundWorker.ReportProgress(int). As you have probably noticed, in most tutorials and examples, people will normally just do a Thread.Sleep(100) inside a for-loop from 1 -> 100 and then send the iteration variable as the argument to ReportProgress.
The easiest solution for you is probably to set the ProgressBarStyle property to Marquee. That way your users can rest assured that your application hasn't frozen and that progress IS being made, although they won't know how long it will take for the operation to complete.
I need to have a progress bar in a popup window, while my main thread is doing some heavy calculations.
I'm using an Oracle API , all the heavy work is done calling 1 function of this API, so I can't use the backgroudworker update becasue I don't have the API's code.
I tried to create a new form with an ProgressBar and a Timer, but the timer_Click event is never fired!!(???)
Any Idea??
while my main thread is doing some heavy calculations.
Wrong. Never do any heavy calculations inside your main thread in a Windows application or your users will simply hate you.
If your API doesn't provide a way to report the progress then the best you could do is show some rotating animation while the calculation is in progress because you will not be able to know the exact percentage of work done. So put the calculation inside a BackgroundWorker, show some spinning animation before running the calculation (which should itself be done inside the DoWork event) and hide the animation once the work is done (RunWorkerCompletedEvent).
The ProgressBar has a Style property that you could set to Marquee to emulate an infinite progression.
I have a MDI form in which, once I click on any menu item, the associated form is shown. Sometimes, forms take time to load, so I would like to show a progress bar for long-running calls.
Since few forms take time to open, you should be moving the form loading code into a separate thread using background worker(This will avoid UI from freezing). You can have WorkerReportsProgress property set to true, so that you can use it to show the progress in the progress bar in ProgressChanged event handler, while the loading.
If you do not have much idea about how to work with Background worker, I recommend you learn how to use them --- See this
Although this is a VB.NET example, the essential part is to get the idea, so I would recommend this excellent article that answers your question:
http://www.dreamincode.net/forums/topic/58239-progress-bar-while-loading-a-child-form/
PS: It would not hurt to google it first.
I have a small application to convert several file formats, with a main windows form which contains several text boxes, buttons, etc. I have another "Document" class which handles all of the actual conversion work, and my form essentially iterates through all of the files, and calls the proper Document methods to convert the files. While this is happening, however, the form stops responding. I created another simple form with a progress bar and a cancel button to spawn when the conversion starts to provide some feedback to our (easily rattled) users. When the new form loads, however, all of the controls are white boxes, and it too stops responding. Once the conversion completes, the progress bar closes properly, and the main form becomes responsive again.
Is there a simple way to make these two forms independent, so that the progress bar can operate even while the other form is unresponsive?
The simplest solution is to have your processing done on a background thread using the BackgroundWorker component. You can drag it in from the VS toolbox. It allows you to update the UI thread with progress notifications so you can update your progress bar to show realistic values (something much more user-friendly than having a "marquee" style progress bar).
You should use two threads so that the form continues to respond while you do work.
This is so common that .NET has a BackgroundWorker control that wraps some of this up for you.
Just call Application.DoEvent() once in a while, probably in your loop.
Not as right as BackgroundWorker, but it's even simpler.
The simplest solution is to have your processing done on a background thread using the BackgroundWorker component. You can drag it in from the VS toolbox. It allows you to update the UI thread with progress notifications so you can update your progress bar to show realistic values (something much more user-friendly than having a "marquee" style progress bar).