1

I have a custom Control derived class for which I want to disable any automatic double buffering completely because I want to handle double buffering manually with a BufferedGraphics object. Drawing is done in OnPaint, Invalidate is called in MouseMove and Resize events for example.

However, if the Control is embedded into a Form with DockStyle.Fill, resizing the form (and subsequently the Control) seems to enable double buffering, no matter what I do. I can see no flicker although the drawing is fairly complex and causes a noticeable delay and the drawing result finally becomes visible.

On the other hand, if the Control is invalidated by a different event (MouseMove) or if I set DockStyle.None and manually resize it (test-wise by a Button), I see the flickering during the drawing process, from which I conclude that double buffering is disabled in this case.

I have ruled out that I am still double buffering with BufferedGraphics (have commented out this part and draw directly to PaintEventArgs.Graphics). Also, setting DoubleBuffered=false or SetStyle(ControlStyles.OptimizedDoubleBuffer, false) inside the constructors of Form and/or Control were not successful.

Leaving the default double buffering on in addition to my manual handling does not seem to make much of a difference performance-wise (probably because building the image in the buffer is much slower than transferring it to screen, even if its done twice). But the redundancy feels a little untidy.

So, how can I disable double buffering for a Resize event that is passed on from the Form to my Control?

oliver
  • 2,771
  • 15
  • 32
  • There is no automatic double buffering, but clipping. By default resize invalidates only changed portions of the rectangle. Set `ResizeRedraw` to `true` and you should get flickering. – Ivan Stoev Jan 07 '18 at 11:37
  • Thanks, but I am afraid, this does not work (I even tried it). I assign my own resize event, which resizes the contained graphics' size parameters and then invalidates the Control. OnPaint gets definitely called (breakpoint). That's what I meant with "and the drawing result finally becomes visible". – oliver Jan 07 '18 at 11:59
  • But what makes me ponder is your statement, that there is no automatic double buffering (not even from the form's perspective?). Is there any way I can find out whether the graphics context passed to OnPaint points to a Double Buffer? – oliver Jan 07 '18 at 12:07
  • First, disregard my previous comment - I've missed that you handle `Resize` and do `Invalidate`. What about checking the graphic inside `OnPaint`, I don't know a public way to do that. Inside the watch window you could check `e.dc` (private field). If it is `IntPtr.Zero`, then the call is with buffered graphics. – Ivan Stoev Jan 07 '18 at 13:34
  • Unfortunately e.dc shows {System.ArgumentNullException} in both cases (with/without the apparent double buffering) in the watch window. I don't even know why accessing this property could reasonably throw an exception btw... – oliver Jan 07 '18 at 14:17

0 Answers0