如何在表单上双缓冲.NET控件?
我怎样才能设置DoubleBuffered
闪烁的窗体上的控件的受保护的DoubleBuffered
属性?
这是一个更通用的Dummy解决scheme 。
我们可以使用reflection来获得受保护的DoubleBuffered属性,然后可以将其设置为true 。
注意 : 如果用户在terminal服务会话中运行 (例如,远程桌面),您应该支付开发人员的税款,而不要使用双缓冲。如果此人在远程桌面上运行,则此辅助方法不会启用双缓冲。
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);
伊恩有更多关于在terminal服务器上使用它的信息。
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上,当我调整控件大小的窗体时,出现了大块的黑色块。 控制现在反弹! 但是更好。
在尝试双缓冲之前,请参阅SuspendLayout()/ ResumeLayout()是否解决您的问题。
扩展方法打开或closures控件的双缓冲
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); } }
用法(例如如何使DataGridView DoubleBuffered):
DataGridView _grid = new DataGridView(); // ... _grid.MakeDoubleBuffered(true);
这让我有了两天的第三方控制的悲痛,直到我追查下来。
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } }
我最近有很多漏洞(粪便)时,重新resize/重绘包含其他控件的控件。
我试过WS_EX_COMPOSITED和WM_SETREDRAW,但没有任何工作,直到我用这个:
private void myPanel_SizeChanged(object sender, EventArgs e) { Application.DoEvents(); }
只是想传递它。
您也可以将控件inheritance到您自己的类中,并在其中设置属性。 这个方法也很好,如果你在所有的控件上都做了很多的设置。
我发现只需在窗体上设置DoubleBuffered设置就可以自动设置这里列出的所有属性。
然而; 我发现winforms提供的双缓冲不是很好。 这个代码片段的小gem 确实有所作为,认真地尝试它。 我花了很长时间寻找一个解决scheme,最终发现:-)
vb.net版本这个好解决scheme….:
Protected Overrides ReadOnly Property CreateParams() As CreateParams Get Dim cp As CreateParams = MyBase.CreateParams cp.ExStyle = cp.ExStyle Or &H2000000 Return cp End Get End Property