Index: System.Windows.Forms/Control.cs =================================================================== --- System.Windows.Forms/Control.cs (revision 66533) +++ System.Windows.Forms/Control.cs (working copy) @@ -118,7 +118,7 @@ private Graphics dc_mem; // Graphics context for double buffering private GraphicsState dc_state; // Pristine graphics context to reset after paint code alters dc_mem private Bitmap bmp_mem; // Bitmap for double buffering control - private bool needs_redraw = true; + private Region undrawn_region; private ControlBindingsCollection data_bindings; @@ -773,6 +773,10 @@ bmp_mem=null; } + if (undrawn_region!=null) { + undrawn_region.Dispose(); + undrawn_region=null; + } if (this.InvokeRequired) { if (Application.MessageLoop) { this.BeginInvokeInternal(new MethodInvoker(DestroyHandle), null, true); @@ -921,6 +925,12 @@ dc_state = dc_mem.Save(); } + private void ImageBufferNeedsRedraw () { + if (undrawn_region != null) + undrawn_region.Dispose(); + undrawn_region = new Region (ClientRectangle); + } + private Bitmap ImageBuffer { get { if (bmp_mem==null) { @@ -947,7 +957,7 @@ bmp_mem = new Bitmap (width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); dc_mem = Graphics.FromImage (bmp_mem); - needs_redraw = true; + ImageBufferNeedsRedraw (); } internal void InvalidateBuffers () @@ -960,7 +970,7 @@ dc_mem = null; bmp_mem = null; - needs_redraw = true; + ImageBufferNeedsRedraw (); } internal static void SetChildColor(Control parent) { @@ -3327,7 +3337,7 @@ } public void Update() { - needs_redraw = true; + ImageBufferNeedsRedraw (); if (IsHandleCreated) { XplatUI.UpdateWindow(window.Handle); } @@ -3971,7 +3981,7 @@ return; } - if (!needs_redraw) { + if (undrawn_region != null && !undrawn_region.IsVisible (paint_event.ClipRectangle)) { // Just blit the previous image paint_event.Graphics.DrawImage (ImageBuffer, paint_event.ClipRectangle, paint_event.ClipRectangle, GraphicsUnit.Pixel); XplatUI.PaintEventEnd(Handle, true); @@ -3979,10 +3989,8 @@ } Graphics dc = null; - Rectangle old_clip_rect = Rectangle.Empty; if (ThemeEngine.Current.DoubleBufferingSupported) { if ((control_style & ControlStyles.DoubleBuffer) != 0) { - old_clip_rect = paint_event.SetClipRectangle (ClientRectangle); dc = paint_event.SetGraphics (DeviceContext); reset_context = true; } @@ -4002,10 +4010,9 @@ if (ThemeEngine.Current.DoubleBufferingSupported) if ((control_style & ControlStyles.DoubleBuffer) != 0) { - paint_event.SetClipRectangle (old_clip_rect); dc.DrawImage (ImageBuffer, paint_event.ClipRectangle, paint_event.ClipRectangle, GraphicsUnit.Pixel); paint_event.SetGraphics (dc); - needs_redraw = false; + undrawn_region.Exclude (paint_event.ClipRectangle); } XplatUI.PaintEventEnd(Handle, true); @@ -4452,7 +4459,7 @@ [EditorBrowsable(EditorBrowsableState.Advanced)] protected virtual void OnInvalidated(InvalidateEventArgs e) { - needs_redraw = true; + ImageBufferNeedsRedraw (); if (Invalidated!=null) Invalidated(this, e); } @@ -4705,7 +4712,7 @@ } } - needs_redraw = true; + ImageBufferNeedsRedraw (); if (VisibleChanged!=null) VisibleChanged(this, e);