Winforms双缓冲

32

我在表单的构造函数中添加了以下代码:

this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);

但是当它加载控件时仍然显示丑陋的伪影,每当它们发生改变时(表单及其组件经常需要更新)。

我需要做些什么不同的事情吗?

1个回答

69

这只对表单本身有影响,而不影响子控件。如果您有很多子控件,它们需要轮流绘制自己,这将花费时间,并在控件所在位置留下一个矩形空洞,直到子控件获得其机会来填充它。

要解决这个问题,您需要双缓冲整个表单和控件。这是自Windows XP之后提供的选项,使WS_EX_COMPOSITED样式标志可用。将以下内容粘贴到您的表单中以启用该选项:

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

它并没有加速绘制过程,但是表格会在延迟后快速出现在屏幕上。这样可以消除可见的绘图问题。真正解决延迟问题需要不使用控件。你可以使用OnPaint方法来绘制“控件”,并使OnMouseClick事件能够智能地识别用户点击了哪个“控件”。


WS_EX_COMPOSITED 只在 Windows 7/Vista 的经典主题下工作,而不在 Aero 主题下工作。有人知道这种情况下的解决方案吗? - KevinBui
它像魔法一样运行良好(这不是指Windows 8的魅力,但我希望它在Windows 8上也能正常工作,如果需要还可以在XP上使用)。 - B. Clay Shannon-B. Crow Raven
我注意到WS_EX_COMPOSITED存在一个问题,就是当拖动位置栏时,滚动条不会绘制。有没有解决方法? - Martin
另外,如果您将此放置在MDI父窗体中,则会修复所有子窗体,而无需在每个窗体类中放置代码片段。 - Nathan
1
这远远超出了我的薪资等级,我感到震惊!谢谢。我简直不敢相信渲染的改进 - “任何足够先进的技术都是不可区分于魔法的”! - SteveCinq
这太棒了。我试图解决这个问题已经几个月了。上帝保佑你! - albusSimba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接