如何在窗体上双缓冲 .NET 控件?
如何在存在闪烁问题的表单上设置控件的受保护 DoubleBuffered
属性?
How can I set the protected DoubleBuffered
property of the controls on a form that are suffering from flicker?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
Ian 有一些有关使用此功能的更多信息在终端服务器上。
Ian has some more information about using this on a terminal server.
这个很好的解决方案的 vb.net 版本......:
vb.net version of this fine solution....:
一种方法是扩展您想要双缓冲的特定控件,并在控件的构造函数内设置 DoubleBuffered 属性。
例如:
One way is to extend the specific control you want to double buffer and set the DoubleBuffered property inside the control's ctor.
For instance:
nobugz 获得了他的链接中的方法,我只是重新发布。 将此覆盖添加到表单中:
这对我来说效果最好,在 Windows 7 上,当我调整控件重型表单的大小时,会出现大的黑色块。 控件现在改为弹跳! 但这样更好。
nobugz gets the credit for the method in his link, I'm just reposting. Add this override to the Form:
This worked best for me, on Windows 7 I was getting large black blocks appearing when I resize a control heavy form. The control now bounce instead! But it's better.
扩展方法打开或关闭控件的双缓冲
用法(例如如何使DataGridView DoubleBuffered):
Extension method to turn double buffering on or off for controls
Usage (for example how to make DataGridView DoubleBuffered):
这让我在两天内对第三方控件感到很多的悲伤,直到我找到它。
最近,我在重新调整大小/重新绘制包含多个其他控件的控件时遇到了很多漏洞(掉落)。
我尝试了 WS_EX_COMPOSITED 和 WM_SETREDRAW 但没有任何效果,直到我使用这个:
只是想传递它。
This caused me a lot of grief for two days with a third party control until I tracked it down.
I recently had a lot of holes (droppings) when re-sizing / redrawing a control containing several other controls.
I tried WS_EX_COMPOSITED and WM_SETREDRAW but nothing worked until I used this:
Just wanted to pass it on.
在尝试双缓冲之前,请查看 SuspendLayout()/ResumeLayout() 是否可以解决您的问题。
Before you try double buffering, see if SuspendLayout()/ResumeLayout() solve your problem.
FWIW
建立在我之前的人的工作之上:
Dummy 的解决方案、Ian Boyd 的解决方案,Amo 的解决方案
这里是通过 PowerShell 中的
SetStyle
设置双缓冲的版本使用反射FWIW
building on the work of those who've come before me:
Dummy's Solution, Ian Boyd's Solution, Amo's Solution
here is a version that sets double buffering via
SetStyle
in PowerShell using reflection我创建了一个静态方法,它接受
Control
并以递归方式将每个子项的DoubleBuffered
属性设置为true
。我使用 DataGridView 创建了一个自定义日历,每次用户与其交互时都会刷新,此方法消除了引起偏头痛的闪烁。
I created a static method that accepts a
Control
and sets theDoubleBuffered
property totrue
to each and every children recursively.I created a custom calendar using
DataGridView
that refreshes everytime the user interacts with it, this method removes the migraine-inducing flicker.您还可以将控件继承到您自己的类中,并在其中设置属性。 如果您倾向于在所有控件上进行大量相同的设置,那么此方法也很好。
You can also inherit the controls into your own classes, and set the property in there. This method is also nice if you tend to be doing a lot of set up that is the same on all of the controls.
我发现只需在表单上设置 DoubleBuffered 设置就会自动设置此处列出的所有属性。
I have found that simply setting the DoubleBuffered setting on the form automatically sets all the properties listed here.
这是Dummy 解决方案的更通用版本。
我们可以使用反射来获取受保护的 DoubleBuffered< /a> 属性,然后可以将其设置为 true。
注意:您应该缴纳开发者税 而不是如果用户在终端服务会话中运行则使用双缓冲< /a>(例如远程桌面)如果用户在远程桌面中运行,则此帮助程序方法将不会打开双缓冲。
Here's a more generic version of Dummy's solution.
We can use reflection to get at the protected DoubleBuffered property, and then it can be set to true.
Note: You should pay your developer taxes and not use double-buffering if the user is running in a terminal services session (e.g. Remote Desktop) This helper method will not turn on double buffering if the person is running in remote desktop.
检查此线程
重复该答案的核心,您可以打开窗口上的 WS_EX_COMPOSITED 样式标志,以使表单及其所有控件都得到双缓冲。 样式标志自 XP 起可用。 它不会使绘画速度更快,但整个窗口都会在屏幕外缓冲区中绘制,并一口气传输到屏幕上。 使其在用户眼中看起来是即时的,而没有明显的绘画伪影。 它并非完全没有问题,某些视觉样式渲染器可能会出现故障,特别是当 TabControl 有太多选项卡时。 YMMV。
将此代码粘贴到您的表单类中:
此技术与 Winform 的双缓冲支持之间的最大区别在于 Winform 的版本一次仅适用于一个控件。 您仍然会看到每个单独的控件绘画本身。 这也可能看起来像闪烁效果,特别是当未绘制的控制矩形与窗口背景形成鲜明对比时。
Check this thread
Repeating the core of that answer, you can turn on the WS_EX_COMPOSITED style flag on the window to get both the form and all of its controls double-buffered. The style flag is available since XP. It doesn't make painting faster but the entire window is drawn in an off-screen buffer and blitted to the screen in one whack. Making it look instant to the user's eyes without visible painting artifacts. It is not entirely trouble-free, some visual styles renderers can glitch on it, particularly TabControl when its has too many tabs. YMMV.
Paste this code into your form class:
The big difference between this technique and Winform's double-buffering support is that Winform's version only works on one control at at time. You will still see each individual control paint itself. Which can look like a flicker effect as well, particularly if the unpainted control rectangle contrasts badly with the window's background.