当前位置:  开发笔记 > 编程语言 > 正文

如何在表单上双重缓冲.NET控件?

如何解决《如何在表单上双重缓冲.NET控件?》经验,为你挑选了7个好方法。

如何DoubleBuffered在遭受闪烁的表单上设置控件的受保护属性?



1> Ian Boyd..:

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


这正是你不想要的.在终端会话中,GDI系统可以发送命令(在这里画线,在这里画圈,在这里填写等).双缓冲是通过将每个绘制到位图上然后使用GDI将整个表单绘制为位图来完成的.通过线路发送未压缩的位图比发送原始GDI命令慢很多*.
@Boris那是因为Windows`TEXTBOX`控件[不遵守任何](http://stackoverflow.com/questions/1955538/win32-how-to-custom-draw-an-edit-control)绘画法则.
@romkyns,如果你需要一个双缓冲的`TextBox`,使用`RichTextBox`并将`DetectUrls`设置为False.如果您希望它可编辑,请使用[EM_SETCHARFORMAT](http://msdn.microsoft.com/en-us/library/windows/desktop/bb774230.aspx)和[EM_SETPARAFORMAT](http://)删除格式msdn.microsoft.com/en-us/library/windows/desktop/bb774276.aspx)消息(示例代码[在这里](http://social.msdn.microsoft.com/Forums/windows/en-US/596ee31b -1eff-4ac9-a68f-b46d7c4059ae /怎么办,我设定的最richtextboxselectionfont-fontFamily中,而无需改变-的风格)).

2> Hans Passant..:

检查这个帖子

重复该答案的核心,您可以打开窗口上的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的版本仅适用于一个控件.您仍然可以看到每个控制油漆本身.这也可能看起来像一个闪烁效果,特别是如果未上漆的控制矩形与窗口的背景形成鲜明对比.



3> 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);

Ian有关于在终端服务器上使用它的更多信息.



4> 小智..:
public void EnableDoubleBuffering()
{
   this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}



5> Jeff Hubbard..:

一种方法是扩展您想要双缓冲区的特定控件,并在控件的ctor中设置DoubleBuffered属性.

例如:

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



6> Chris S..:

nobugz在他的链接中得到了方法的功劳,我只是重新发布.将此覆盖添加到窗体:

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

这对我来说效果最好,在Windows 7上,当我调整控件重型窗口时,我出现了大的黑色块.控制现在反弹!但它更好.


我是nobugz,我在MSDN论坛上使用过的昵称.

7> MajesticRa..:

扩展方法为控件打开或关闭双缓冲

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);

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有