任何人都可以解释
之间的区别和关系SetStyle(ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer, true)
和
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
他们需要减少闪烁,但是何时以及如何正确使用它们?它们可以单独使用,还是必须成对使用,这是什么原因?
谢谢!
积分:
第一个代码段引自MSDN page;第二个代码段在How to fix the flickering in User controls上找到,原作者是@HansPassant。
答案 0 :(得分:9)
感谢@terrybozzlo的解释,感谢@Caramiriel这个澄清问题的精彩页面。
我想总结一下我来到这里的所有内容。
当您的表单或容器控件(例如Panel
)包含太多控件(以及启用WS_CLIPCHILDREN
时默认情况下)时,通常会出现闪烁现象。根据@HansPassant:
它绘制了BackgroundImage,在子控件窗口的位置留下了空洞。然后每个子控件都会收到一条消息来绘制自己,他们将用他们的窗口内容填充这个洞。当您有很多控件时,用户可以看到这些漏洞一段时间。它们通常是白色的,在黑暗时与BackgroundImage形成鲜明对比。或者如果表单设置了Opacity或TransparencyKey属性,它们可能是黑色的,与几乎任何东西形成鲜明对比。
您应该将Control的DoubleBuffered
属性设置为true
。为此,您需要从基本类型派生控件(如果它不是用户控件)并在构造函数中设置它。
例如,要获得Panel
双缓冲,您需要执行以下操作:
public class BufferedPanel : Panel
{
public BufferedPanel()
{
DoubleBuffered = true;
}
}
或者,您可以使用:
SetStyle(ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer, true);
获得相同效果,即等效。
上述技术将减少控制级别的闪烁,这意味着当重新绘制表单时,所有控件都不会再闪烁。但最终的解决方案是减少表单级别的闪烁:当表单重新绘制时,表单及其所有子项都是双缓冲的。
这需要覆盖CreateParams
:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
SetStyle
在控件级别上完成工作,在表单级别上完成CreateParam
,并为表单内的所有控件实现双缓冲。
@terrybozzlo,@ Caramiriel,@ HansPassant