2012-02-03 88 views
6

我有几个使用GDI +绘制到屏幕上的自定义(winforms)组件。什么可能导致Double Buffering杀死我的应用程序?

为了防止闪烁的重绘,我决定启用双缓冲,所以我加了一条线,我的构造函数:

public ColourWheel() 
{ 
    InitializeComponent(); 
    this.DoubleBuffered = true; 
} 

该组件(ColourWheel)上正常工作。当我同行添加到任何我的另外两个(类似结构的)部件的构造函数中,我得到了几个奇怪的症状:

  1. 当我尝试与部件运行的形式,我得到一个参数例外Application.Run(new Form());
  2. 如果我切换到设计模式,我得到一个关于组件有一个未处理的异常与一个参数有关的错误。

我是不是在将一个或所有的缓冲区变成双缓冲区,它仍然可以在ColourWheel上工作,但不是其他的。

为了记录,我也尝试了其他一些doublebuffering技术。

什么可能导致双缓冲工作在一个组件上,而不是其他工作?


编辑:下面是从运行时症状异常详细信息:

System.ArgumentException是未处理消息=参数不 有效。源= System.Drawing中堆栈跟踪: 在System.Drawing.Graphics.GetHdc() 在System.Drawing.BufferedGraphics.RenderInternal(HandleRef refTargetDC,BufferedGraphics缓冲液) 在System.Drawing.BufferedGraphics.Render() 在System.Windows .Forms.Control.WmPaint(消息&米) 在System.Windows.Forms.Control.WndProc(消息&米) 在System.Windows.Forms.ScrollableControl.WndProc(消息&米) 在System.Windows.Forms的.UserControl.WndProc(Message & m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message & m) at System.Windows.Forms.Co ntrol.ControlNativeWindow.WndProc(消息&米) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr的的HWND,MSG的Int32,IntPtr的WPARAM,IntPtr的LPARAM) 在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG & MSG) 在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr的 dwComponentID,的Int32原因,的Int32 pvLoopData) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(的Int32 原因,ApplicationContext上下文) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext context) at S ystem.Windows.Forms.Application.Run(Form mainForm) at TestForm.Program。Main()in D:\ Documents and Settings \ Tom Wright \ My Documents \ Visual Studio 2010 \ Projects \ ColourPicker \ TestForm \ Program.cs:line 18 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,String [] args) 在System.AppDomain.ExecuteAssembly(字符串assemblyFile,证据assemblySecurity,字串[] args) 在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在的System.Threading .ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态,Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state) 在System.Threading.ThreadHelper.ThreadStart()的InnerException:


编辑2:从两个组件中的一个(更复杂)的OnPaint处理导致问题:

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); 
       } 
      } 
     } 
} 
+0

请分享例外。 – roken 2012-02-03 19:48:48

+1

@roken你的朋友。 – 2012-02-03 19:54:02

+0

您是否在违规控件中重写OnPaint()?如果是这样,那是什么样子? – roken 2012-02-03 20:52:30

回答

8

Paint事件期间,您不应该处置借给您的Graphics对象,这就是您的using阻止的不当行为。

的症状是下一次Paint事件触发,你会得到同样Graphics对象回来,但它不再绑定到一个内存HDC,导致在你的堆栈跟踪看到Graphics.GetHdc()失败。

  1. 这是可能的,它会超越单一Paint事件(这是很可能与双缓冲的情况下,虽然它也可以用单缓冲如果CS_OWNDC窗口样式设置)。

  2. Paint事件可以有多个处理程序。

因此,事件处理程序不应该呼吁Graphics对象Dispose或允许using块这样做。相反,在框架Paint事件处理完成后,.NET框架会根据需要清理资源。

+1

它工作了一年,然后当我将用户控件类移到它自己的文件开始抛出错误OP在这里得到。你建议的工作 - 有时候C#可能真的很奇怪! – 2014-04-08 07:25:36

1

你应该在另一台机器上测试它,看它是否只是你的电脑。大多数情况下,这不应该由于双缓冲而发生,而是检查是否正在处理不应该在Paint事件中的任何元素,或者在代码中执行任何会执行两次的问题。

+2

我不认为你应该在'Paint'事件期间处理给你的'Graphics'对象。 – 2012-02-03 20:34:49

+0

@ben是对的。不要在'g'上做一个'使用',因为当你退出该范围时,它将处理Graphics对象,但你不是该对象的'所有者'。 – 2012-02-04 10:06:55

+0

谢谢你们。我在做'使用(Graphics g = e.Graphics){}'。解决这个问题是关键。 – 2012-02-04 10:21:11

相关问题