如何DoubleBuffered
在遭受闪烁的表单上设置控件的受保护属性?
这是Dummy解决方案的更通用版本.
我们可以使用反射来获取受保护的DoubleBuffered属性,然后可以将其设置为true.
注意:如果用户在终端服务会话中运行(例如远程桌面),则应支付开发者税,而不是使用双缓冲.如果此人在远程桌面上运行,则此助手方法不会启用双缓冲.
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); }
检查这个帖子
重复该答案的核心,您可以打开窗口上的WS_EX_COMPOSITED样式标志,以使表单及其所有控件双重缓冲.样式标志自XP起可用.它不会使绘画更快,但是整个窗口都是在屏幕外缓冲区中绘制的,并且在一次打击中对屏幕进行了打开.使用户的眼睛立即看起来没有可见的绘画工件.它并非完全没有问题,一些视觉样式渲染器可能会出现问题,特别是当TabControl有太多标签时.因人而异.
将此代码粘贴到表单类中:
protected override CreateParams CreateParams { get { var cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED return cp; } }
这种技术与Winform的双缓冲支持之间的最大区别在于Winform的版本仅适用于一个控件.您仍然可以看到每个控制油漆本身.这也可能看起来像一个闪烁效果,特别是如果未上漆的控制矩形与窗口的背景形成鲜明对比.
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control) .GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); aProp.SetValue(ListView1, true, null);
Ian有关于在终端服务器上使用它的更多信息.
public void EnableDoubleBuffering() { this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); this.UpdateStyles(); }
一种方法是扩展您想要双缓冲区的特定控件,并在控件的ctor中设置DoubleBuffered属性.
例如:
class Foo : Panel { public Foo() { DoubleBuffered = true; } }
nobugz在他的链接中得到了方法的功劳,我只是重新发布.将此覆盖添加到窗体:
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } }
这对我来说效果最好,在Windows 7上,当我调整控件重型窗口时,我出现了大的黑色块.控制现在反弹!但它更好.
扩展方法为控件打开或关闭双缓冲
public static class ControlExtentions { ////// Turn on or off control double buffering (Dirty hack!) /// /// Control to operate /// true to turn on double buffering 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); } }
用法(例如,如何使DataGridView DoubleBuffered):
DataGridView _grid = new DataGridView(); // ... _grid.MakeDoubleBuffered(true);