views:

138

answers:

2

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?

+1  A: 

The Paint event of WindowsForms controls usually has a context region set to only redraw the parts of the control that are necessary. This, combined with setting DoubleBuffered to true is usually enough for most repainting issues.

Also, you're getting the exception because the Graphics object 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 Bitmap when you then paint on screen in your Paint event. Or, host the bitmap in a PictureBox and let the redrawing happen automatically.

Bevan
Thanks for your helpful answer, you've given me a few ideas to explore. I'll take another look later this week and accept your answer if it all works out :).
Pourquoi Litytestdata
I'm now using DoubleBuffered and restricting the redraw area to the clip rectangle in the Paint event, and it's working much better now. It's a bit more work than with Qt. It also reminds me of writing window redraw code in RISC OS - happy days! :) Thanks again.
Pourquoi Litytestdata
A: 

a v.quick thought - what about trying PyQt? the QCanvas and a QCanvasView should work properly on any platform

Geddes
I already use PyQt. In fact, it's what I've done all my Qt programming with! The point of this exercise, however, was to learn Windows Forms, so using PyQt would have been self-defeating.
Pourquoi Litytestdata
OK, cool - it was just a thought. All the best to you and good luck with the Shikaku project.
Geddes