如何在窗体上加倍缓冲.NET控件?

时间:2020-03-05 18:57:11  来源:igfitidea点击:

如何在出现闪烁的窗体上设置控件的" DoubleBuffered"受保护属性?

解决方案

回答

public void EnableDoubleBuffering()
{
   this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}

回答

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)有一些有关在终端服务器上使用它的更多信息。

回答

我们还可以将控件继承到自己的类中,并在其中设置属性。如果我们倾向于在所有控件上进行很多相同的设置,则此方法也很好。

回答

一种方法是扩展要加倍缓冲的特定控件,并在控件的ctor中设置DoubleBuffered属性。

例如:

class Foo : Panel
{
    public Foo() { DoubleBuffered = true; }
}

回答

在尝试双缓冲之前,请查看SuspendLayout()/ ResumeLayout()是否解决了问题。

回答

这是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); 
}

回答

我发现只需在窗体上设置DoubleBuffered设置即可自动设置此处列出的所有属性。

然而;我发现Winforms提供的双重缓冲效果不佳。这段代码片段的这个小地方确实有所作为,请认真尝试。我花了很长时间寻找一种可行的解决方案,最终发现:-)

回答

检查这个线程

重复该答案的核心,我们可以在窗口上打开WS_EX_COMPOSITED样式标志,以使窗体及其所有控件都得到双缓冲。从XP开始,样式标记可用。它并不能使绘制速度更快,但是整个窗口是在屏幕外缓冲区中绘制的,并且一拳打在屏幕上。使它在用户的眼睛上立即可见,而没有可见的绘画瑕疵。它并非完全没有问题,某些视觉样式渲染器可能会在其上出现故障,尤其是TabControl的选项卡过多时。 YMMV。

将此代码粘贴到表单类中:

protected override CreateParams CreateParams {
    get {
        var cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;    // Turn on WS_EX_COMPOSITED
        return cp;
    } 
}

该技术与Winform的双缓冲支持之间的最大区别是Winform的版本一次只能在一个控件上运行。我们仍然会看到每个单独的控件画图本身。看起来也像是闪烁效果,特别是如果未绘制的控件矩形与窗口背景形成鲜明对比时。

回答

nobugz在他的链接中获得了该方法的荣誉,我只是在重新发布。将此替代添加到表单中:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

这对我来说效果最好,在Windows 7上,当我调整控件较重的窗体的尺寸时,会出现大的黑色块。控件现在反跳了!但是更好。