I’ve written a Windows Forms application to solve Shikaku puzzles. At the moment, the puzzle grid is drawn on a Panel in the app’s main window using a PaintEventHandler. The method called by the PaintEventHandler redraws the entire grid every time it is called. Whilst this approach works, it is flickery and inefficient, and I would like to replace it with something smoother.
I’ve written a number of similar applications in Qt. With Qt, I’d create a QCanvas and a QCanvasView. I can then add objects to, or remove objects from, the QCanvas and call the update() method on the QCanvasView to see the changes take effect without flicker.
One alternative approach I have tried was to keep a reference to the Graphics object used to paint the Panel and attempt to draw on it outside of a Paint event. This didn’t work: I got a rather unhelpful ArgumentException: Parameter is not valid exception, which I can only assume was thrown by Windows because it wasn’t expecting the app to do any painting at that point.
Is there something similar to a QCanvas for Windows Forms? If not, what approach should I use to update the puzzle grid?
The
Paintevent of WindowsForms controls usually has a context region set to only redraw the parts of the control that are necessary. This, combined with settingDoubleBufferedto true is usually enough for most repainting issues.Also, you’re getting the exception because the
Graphicsobject you’re caching is Disposed when the paint event is finished.One viable approach, assuming DoubleBuffering isn’t sufficient, is to do your drawing to an offscreen
Bitmapwhen you then paint on screen in your Paint event. Or, host the bitmap in aPictureBoxand let the redrawing happen automatically.