【发布时间】:2012-02-26 09:32:11
【问题描述】:
我有一些使用 GDI+ 在屏幕上绘制的自定义(winforms)组件。
为了防止重绘时闪烁,我决定启用双缓冲,所以我在构造函数中添加了一行:
public ColourWheel()
{
InitializeComponent();
this.DoubleBuffered = true;
}
在这个组件(ColourWheel)上效果很好。当我将同一行添加到其他两个(结构相似)组件中的任何一个的构造函数中时,我得到了一些奇怪的症状:
- 当我尝试在打开组件的情况下运行表单时,
Application.Run(new Form());上出现参数异常。 - 如果我切换到设计模式,我会收到有关组件存在与参数有关的未处理异常的错误消息。
我是否在其中一个或全部上打开双缓冲似乎并不重要,它仍然适用于 ColourWheel,但不适用于其他。
为了记录,我还尝试了一些其他 double buffering 技术。
什么可能导致双缓冲在一个组件上起作用,而在其他组件上不起作用?
编辑:这是运行时症状的异常详细信息:
System.ArgumentException 未处理 Message=Parameter is not 有效的。源 = System.Drawing StackTrace: 在 System.Drawing.Graphics.GetHdc() 在 System.Drawing.BufferedGraphics.RenderInternal(HandleRef refTargetDC,BufferedGraphics 缓冲区) 在 System.Drawing.BufferedGraphics.Render() 在 System.Windows.Forms.Control.WmPaint(消息和 m) 在 System.Windows.Forms.Control.WndProc(消息和 m) 在 System.Windows.Forms.ScrollableControl.WndProc(消息和 m) 在 System.Windows.Forms.UserControl.WndProc(消息和 m) 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息& m) 在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(消息和 m) 在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) 在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(味精和味精) 在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 原因, Int32 pvLoopData) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 原因,ApplicationContext 上下文) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 原因,ApplicationContext 上下文) 在 System.Windows.Forms.Application.Run(窗体 mainForm) 在 D:\Documents and Settings\Tom Wright\My Documents\Visual Studio 中的 TestForm.Program.Main() 2010\Projects\ColourPicker\TestForm\Program.cs:第 18 行 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数) 在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback 回调, 对象状态, Boolean 忽略SyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 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);
}
}
}
}
【问题讨论】:
-
您是否在有问题的控件中覆盖 OnPaint()?如果是这样,那是什么样的?
-
@roken 我正在编辑我的问题以包含我的 OnPaint 处理程序。
标签: c# components gdi+ double-buffering