I have a Canvas that needs to refresh itself several times in the course of a method (contains multiple nested if statements with different actions). The canvas Refresh is called, but the canvas Paint event is not triggered until after the method completes, which means some interesting interim stuff is not displayed. I have also tried canvas Invalidate, but it does not change what is happening.
Break up your code into sections, each followed by a canvas.invalidate. Run each section in a timer, keeping track of where you are. Eg.,
select case NextAction
// section1 code
NextAction = "Section2"
// section2 code
NextAction = "Section3"
// section3 code
NextAction = ""
// exit, let the canvas update and then run the next section of code
if NextAction <> "" then me.RunMode = Timer.RunModes.Single
Put your code into a thread and yield after each canvas refresh/invalidate
within your method should do what you want, but it might cause unexpected results though.
from the documentation
Using DoEvents in a GUI application will likely cause instability . In effect, you would be placing a main event loop inside the “real” main event loop. You should consider using threadsto handle lengthy operations rather than placing them in the main thread and calling DoEvents to maintain the interface.
If the current method is running inside a Thread, DoEvents will yield to the main thread instead of running one iteration of the event loop inside the thread, causing confusion.
If you use DoEvents inside a loop, then you cannot use the UserCancelled function to detect whether the user pressed the Esc key (Windows or Linux) or Command-period (on Macintosh) to break out of the loop. Since DoEvents keeps the user interface responsive while the loop is running, you can add a button to the user interface that the user can click to stop the loop.