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