Recently soomeone asked me why I used Invalidate in an example instead of using Refresh to make a control redraw itself. Both of these make the control's Paint event handler execute so why would you pick one over the other?
For my purposes, I don't think it generally matters which you use. Here's an interesting post that explains the differences between Invalidate, Update, and Refresh.
As I understand it:
So when would you use one or the other?
- Invalidate marks the window as invalid so it gets redrawn the next time it's events are processed. that means this isn't synchronous.
- Update sends a WM_PAINT to the control if its update region isn't empty.
- Refresh Calls Invalidate and then Update to refresh synchronously.
Well, the "normal" way to make a form do things is to dump messages into its message queue and let it get to them when it can. That's what invalidate does.
Refresh forces the window to handle messages out of order. In theory I suppose that could cause unnecessary redraws. Normally the window's invalid areas are added up and when there's time the window redraws them all at once. Refresh would force each one to redraw separately.
In practice I doubt this is an issue for most programs.
The only reasonable time I can think of where the difference matters is if you are doing something that performs a lot of calculations and you want to force the redraw immediately even if the program is hogging the CPU so much the message queue isn't making much progress. In that case, you would need to use Refresh.
So could you use Refresh always? Probably. It seems like a situation where it would cause problems would be rare.
Boops Boops had this important note to add:
I can think of situations where I think Invalidate is the right choice.
GDI+ sometimes needs a fair amount of time to draw what you want it to draw. For example, you might be superimposing several image layers with partial transparency in a picture box. Or you could be drawing an elaborate shape, for example with DrawString or GraphicsPath.Addstring. You might also be doing some artistic colouring with a PathGradientBrush. And, especially, some combination of these things.
All is fine as long as the image doesn't change. But suppose you are dragging a component of the image with the mouse. If you Refresh the picture box on every MouseMove, the effect could be jerky and slow because the MouseMove events fire faster than GDI+ can draw in the new location.
This effect could also show up if you do an animation and you use Refresh on every Timer.Tick. Drawing the image can take longer than the timer interval, so the effect will be to slow the frame rate down. In this situation, which is better depends on the character of the animation. An image going through a dynamic morph would be better off Refreshed (even if it is slower), since skipping intermediate frames would look bad. But a sprite in motion across the screen would be better off with Invalidate, since that could allow unnecessary frames to be skipped without spoiling the illusion of motion.
Invalidate lets you specify rectangle to be refreshed. When dragging a sub-image with the mouse, you only need to invalidate the previous bounds and the new bounds, not necessarily the whole control. And similarly for clocked animation. This can be an important factor in getting a smooth animation when pixel drawing time is tight.
To sum up, I think it is useful to remind people that there is a real choice between Refresh and Invalidate, possibly followed by Update. In situations where performance is an issue, it may be worth trying one then the other to see which gives the best results. The comparison also depends on the graphics hardware, so a serious graphics programmer must take that into account when choosing a method.