I have a progressbar set to invisible, but when it goes thru a loop is turned on and updated as each listItem of a listbox is checked. It works fine if have a msgbox each time it updates telling me its value, but when I remove that msgBox the progressbar doesn’t even show up. It just runs the loop and never appears. Here is my code:
This sounds to me like you are trying to update the UI within a tight loop. This will usually result in the behavior you are seeing (or not seeing, as the case may be…).
Rather than trying to update the progress bar within the loop, I suggest storing the progress value in a property. Then, add a timer to your window with a small period. Before the loop, set the timer’s mode to Timer.Mode.ModeMultiple. After the loop, set the timer’s mode to Timer.Mode.ModeOff. In the Timer’s Action event, read the progress value property’s value and set the Progress Bar’s value to that. This will allow the UI to update in the tight loop.
Batting 0 here unfortunately. Tried setting up the timer as per Scott, but it didn’t seem to change anything. Also tried Timer1.Invalidate, but it said “timer has no member named invalidate”. Also tried setting it up exactly like the example UpdateUIFromThread but I get the error:
“Exception Message: A thread has attempted to manipulate a user interface element. This can only be done from the application’s main thread.”
I originally tried to set this up like I did in a project I have made in RS2011 R4.3, but that’s where it was just not showing up unless i added the msgbox.
Retrying Scott’s again now. Perhaps I missed something.
Long and the short of your problem is that Window services haven’t yet had time to make the progressbar visible, so any calls to updating it are just wasting cycles.
You can fix this with a bunch of solutions.
Use a short delay timer to do your work, so that there’s a gap between the action being selected and the task starting, giving Window services a few milliseconds to make the progressbar visible. You must use Refresh here as invalidate is coalesced and won’t update until your task has finished.
Use a thread, like others have suggested, so that the window can be updated while the thread is running.
Use a helper application, the most complex solution, but you’ll get the best the performance and a smooth updating interface.
The hackiest solution of all is to use app.doevents after calling progressbar.refresh. This will pause your work for a specified time duration and allow other things to kick in and update. Xojo warns against this function as it can lead to undesired results.
yeah i set it up exactly as the example app and even named everything the same. I got the LongRunningMethod to run and the progressbar displayed correctly, but as soon as I add my method to this i get the Exception message above. My method has to do an httpsocket and check the results. Could that have something to do with the error?
I’ll keep banging on this for a while and see what I can figure out. thanks for the help.
You might want to use a short-period timer where every time the timer fires it processes the next row of the listbox. That would a) allow you to access the UI from your code, and b) yield time to the UI to redraw the progressbar. You can vary the number of rows it processes each time to “tune” the performance of it.
Yes. In your thread, you work with Values which can be a Property of the Window or a Module, for example. In your Timer you can Update the ListBox and the Progressbar depending on the same Values you use in the Thread.
BTW: You can start a Timer from within a Thread, because a Timer is no UI Element.