I have several winforms components that draw on the screen using GDI +.
To prevent flickering when redrawing, I decided to enable double buffering, so I added a line to my constructor:
public ColourWheel() { InitializeComponent(); this.DoubleBuffered = true; }
Which works great on this component (ColourWheel). When I add the same line to the constructor of any of the other two (similarly structured) components, I get some strange symptoms:
- When I try to run a form with the component turned on, I get an Argument Exception on
Application.Run(new Form());
. - If I switch to development mode, I get an error when a component that has an unhandled exception can use a parameter.
It doesn't seem to matter if I rotate double buffering on one or all of them, it still works on ColourWheel, but not on the others.
For the record, I also tried several other buffering .
What can cause double buffering to work with one component, but not with the other?
EDIT: Here is the detail of the exception to the symptom at runtime:
System.ArgumentException was unhandled Message = Parameter is not valid. Source = System.Drawing StackTrace: in System.Drawing.Graphics.GetHdc () in System.Drawing.BufferedGraphics.RenderInternal (HandleRef refTargetDC, BufferedGraphics buffer) in System.Drawing.BufferedGraphics.Render () in System.Windows.Forms.Control .WmPaint (Message & m) in System.Windows.Forms.Control.WndProc (Message & m) in System.Windows.Forms.ScrollableControl.WndProc (Message & m) in System.Windows.Forms.UserControl.WndProc (Message & m) in System.Windows.Forms.Control.ControlNativeWindow.OnMessage (Message & m) in System.Windows.Forms.Control.ControlNativeWindow.WndProc (Message & m) in System.Windows.Forms.NativeWindow.DebuggableCallback (IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) in System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW (MSG & msg) in System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManagerMessagerManager IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) in System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner (Int32 reason, ApplicationContext context) in System.Windows.Forms.Application.ThreadContext.RunMessageLoop (Int32 reason, Windows.Forms.Application.Run (Form mainForm) in TestForm.Program.Main () in D: \ Documents and Settings \ Tom Wright \ My Documents \ Visual Studio 2010 \ Projects \ ColorPicker \ TestForm \ Program.cs: line 18 in System.AppDomain._nExecuteAssembly (assembly RuntimeAssembly, String [] args) in System.AppDomain.ExecuteAssembly (String assemblyFile, Evidence assemblySecurity, String [] args) in Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssThread.Thread. System.readun.read .ThreadStart_Context (object state) in System.Threading.ExecutionContext.Run (ExecutionCo ntext executeContext, ContextCallback callback, object state, boolean ignoreSyncCtx) in System.Threading.ExecutionContext.Run (ExecutionContext executeContext, ContextCallback callback, object state) in System.Threading.ThreadHelper.ThreadStart () InnerException:
EDIT 2: OnPaint handler from one (more complex) of two components causing problems:
private void ValueSlider_Paint(object sender, PaintEventArgs e) { using (Graphics g = e.Graphics) { g.DrawImage(this.gradientImage, new Rectangle(0, 0, paintArea.Width, paintArea.Height)); if (this.showmarker) { ColourHandler.HSV alt = ColourHandler.RGBtoHSV(new ColourHandler.RGB(this.SelectedColour.R, this.SelectedColour.G, this.SelectedColour.B)); alt.Saturation = 0; alt.value = 255 - alt.value; using (Pen pen = new Pen(ColourHandler.HSVtoColour(alt))) { pen.Width = (float)MARKERWIDTH; g.DrawRectangle(pen, 0 - pen.Width, this.brightnessPoint.Y - MARKERWIDTH, this.paintArea.Width + (pen.Width * 2), MARKERWIDTH * 2); } } } }