C# 如何在表单上加倍缓冲 .NET 控件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/76993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to double buffer .NET controls on a form?
提问by Ian Boyd
How can I set the protected DoubleBuffered
property of the controls on a form that are suffering from flicker?
如何DoubleBuffered
在遭受闪烁的窗体上设置控件的受保护属性?
采纳答案by Ian Boyd
Here's a more generic version of Dummy's solution.
这是Dummy 解决方案的更通用版本。
We can use reflection to get at the protected DoubleBufferedproperty, and then it can be set to true.
我们可以使用反射来获取受保护的DoubleBuffered属性,然后可以将其设置为true。
Note: You should pay your developer taxesand not use double-buffering if the user is running in a terminal services session(e.g. Remote Desktop) This helper method will not turn on double buffering if the person is running in remote desktop.
注意:如果用户在终端服务会话(例如远程桌面)中运行,您应该支付开发人员税并且不要使用双缓冲,如果该人在远程桌面上运行,则此辅助方法将不会打开双缓冲。
public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
//Taxes: Remote Desktop Connection and painting
//http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
return;
System.Reflection.PropertyInfo aProp =
typeof(System.Windows.Forms.Control).GetProperty(
"DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(c, true, null);
}
回答by Arno
public void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
}
回答by dummy
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);
Ianhas some more information about using this on a terminal server.
Ian有一些关于在终端服务器上使用它的更多信息。
回答by MagicKat
You can also inherit the controls into your own classes, and set the property in there. This method is also nice if you tend to be doing a lot of set up that is the same on all of the controls.
您还可以将控件继承到您自己的类中,并在其中设置属性。如果您倾向于在所有控件上进行大量相同的设置,则此方法也很好。
回答by Jeff Hubbard
One way is to extend the specific control you want to double buffer and set the DoubleBuffered property inside the control's ctor.
一种方法是扩展要加倍缓冲的特定控件并在控件的构造函数中设置 DoubleBuffered 属性。
For instance:
例如:
class Foo : Panel
{
public Foo() { DoubleBuffered = true; }
}
回答by Joel Coehoorn
Before you try double buffering, see if SuspendLayout()/ResumeLayout() solve your problem.
在尝试双缓冲之前,请查看 SuspendLayout()/ResumeLayout() 是否解决了您的问题。
回答by ljs
I have found that simply setting the DoubleBuffered setting on the form automatically sets all the properties listed here.
我发现只需在表单上设置 DoubleBuffered 设置就会自动设置此处列出的所有属性。
回答by Hans Passant
Check this thread
检查这个线程
Repeating the core of that answer, you can turn on the WS_EX_COMPOSITED style flag on the window to get both the form and all of its controls double-buffered. The style flag is available since XP. It doesn't make painting faster but the entire window is drawn in an off-screen buffer and blitted to the screen in one whack. Making it look instant to the user's eyes without visible painting artifacts. It is not entirely trouble-free, some visual styles renderers can glitch on it, particularly TabControl when its has too many tabs. YMMV.
重复该答案的核心,您可以打开窗口上的 WS_EX_COMPOSITED 样式标志以使窗体及其所有控件双缓冲。样式标志从 XP 开始可用。它不会使绘画更快,但整个窗口都在屏幕外缓冲区中绘制,并在一次重击中传输到屏幕。使其在用户眼中即刻呈现,而没有可见的绘画伪像。它并非完全没有问题,一些视觉样式渲染器可能会出现故障,特别是 TabControl 当它有太多选项卡时。天啊。
Paste this code into your form class:
将此代码粘贴到您的表单类中:
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
The big difference between this technique and Winform's double-buffering support is that Winform's version only works on one control at at time. You will still see each individual control paint itself. Which can look like a flicker effect as well, particularly if the unpainted control rectangle contrasts badly with the window's background.
这种技术与 Winform 的双缓冲支持之间的最大区别在于 Winform 的版本一次仅适用于一个控件。您仍然会看到每个单独的控件绘制本身。这也可能看起来像闪烁效果,特别是如果未绘制的控件矩形与窗口的背景形成鲜明对比。
回答by Chris S
nobugzgets the credit for the method in his link, I'm just reposting. Add this override to the Form:
nobugz在他的链接中获得了该方法的功劳,我只是重新发布。将此覆盖添加到表单:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
This worked best for me, on Windows 7 I was getting large black blocks appearing when I resize a control heavy form. The control now bounce instead! But it's better.
这对我来说效果最好,在 Windows 7 上,当我调整控件重窗体的大小时,出现了大的黑色块。控制现在反弹!但它更好。
回答by MajesticRa
Extension methodto turn double buffering on or off for controls
为控件打开或关闭双缓冲的扩展方法
public static class ControlExtentions
{
/// <summary>
/// Turn on or off control double buffering (Dirty hack!)
/// </summary>
/// <param name="control">Control to operate</param>
/// <param name="setting">true to turn on double buffering</param>
public static void MakeDoubleBuffered(this Control control, bool setting)
{
Type controlType = control.GetType();
PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(control, setting, null);
}
}
Usage (for example how to make DataGridView DoubleBuffered):
用法(例如如何使 DataGridView DoubleBuffered):
DataGridView _grid = new DataGridView();
// ...
_grid.MakeDoubleBuffered(true);