如何使标签在加载时透明而不闪烁
我有一个面板,上面有一个图片框。我必须在面板中显示大约 20 个标签。我希望标签的背景是透明的,即显示图片框中的图像,而标签仅显示文本。 现在,由于标签没有表现出真正的透明度,我将标签设为图片框的子标签,
this.lbl1.Parent = pictureBox1;
这解决了我眼前的问题,但现在当表单加载时,所有标签都需要一段时间才能变得可见,并且一次一个。如果你们能为此提供一些解决方案,我将不胜感激。
提前致谢
I have a panel and on that I've a picturebox. There are around 20 labels that I've to show in the panel. I want the background of Label to be transparent ie the image in picturebox is shown and the label displays only the text.
Now since labels do not exhibit true transparency I made the labels child of picturebox
this.lbl1.Parent = pictureBox1;
This has solved my immediate problem but now when the form loads, all the labels take a while to become visible and do so one at a time. I'd appreciate if you guys can give some solution for this.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
闪烁的标准解决方法是双缓冲。但这并不能解决这种闪烁。这是一种不同的类型,是由多个窗口相互重叠引起的。每个标签都是它自己的窗口。当窗体需要绘制自身时,它会绘制其背景,为子窗口留下孔。然后每个子窗口轮流绘制自己。接下来他们的子窗口会自动绘制。等等。
当一个控件(毫无疑问是图片框)需要一段时间来绘制时,这一点就会变得很明显。特别是当它显示需要调整大小的大图像时。当图片框绘制时,子窗口的孔保持未绘制状态。它们具有白色背景,当您使用表单的 TransparencyKey 或 Opacity 属性时,它们具有黑色背景。这可能与图片框中的图像形成鲜明对比,这种效果被用户视为闪烁。
一种直接的解决方法是不使用控件,这样您就不必为它们的窗口付费。 Label 非常方便,但是仅仅为了显示一个字符串而烧毁一个窗口是对系统资源的巨大浪费。您可以简单地实现图片框的 Paint 事件并使用 TextRenderer.DrawText() 绘制字符串。 PictureBox 默认开启双缓冲,因此图像和文本的绘制完全流畅,不再闪烁。明显的缺点是你失去了点击的便利性,你必须编写代码。
还有其他可能的修复方法。其中之一是防止图片框为子窗口留下孔洞。它将绘制整个图像,标签弹出在图像之上。这仍然是闪烁,但不那么明显了。将新类添加到您的项目中并粘贴以下代码:
编译新的图片框控件并将其从工具箱顶部拖放到窗体上。
另一种可能的解决方法是使表单及其所有子项都进行双缓冲。这根本不会加快绘画速度,但所有窗口都会渲染到内存缓冲区中,结果会传输到屏幕上。您会注意到延迟,但窗口突然在屏幕上弹出。这称为合成。 Winforms 不直接支持这一点,因为它可能有副作用,但它很容易启用。将此代码粘贴到您的表单类中:
XP 及更高版本支持。留意绘画文物。
The standard cure for flicker is double-buffering. But that cannot solve this kind of flicker. It is a different kind, caused by having multiple windows overlapping each other. Each label is its own window. When the form needs to paint itself, it draws its background leaving holes for the child windows. Each child window then takes a turn drawing itself. And their child windows draw themselves next. Etcetera.
This becomes noticeable when one control takes a while to draw, no doubt your picture box. Especially when it displays a large image that needs to be resized. The holes for the child windows stay unpainted while the picture box draws. They have a white background, black when you use the form's TransparencyKey or Opacity property. This can contrast badly with the image in your picture box, that effect is perceived by the user as flicker.
One immediate cure is to not use controls so you don't pay for their window. A Label is very convenient but it is a massive waste of system resources to burn up a window just to display a string. You can simply implement the picture box' Paint event and draw the strings with TextRenderer.DrawText(). PictureBox has double-buffering turned on by default so the image as well as the text is drawn completely smoothly, no more flicker. The obvious disadvantage is that you lose the convenience of point-and-click, you have to write code.
There are other fixes possible. One of them is to prevent the picture box from leaving holes for the child windows. It will draw the entire image, the labels pop on top of them. That's still flicker but not nearly as noticeable. Add a new class to your project and paste this code:
Compile and drop the new picture box control from the top of the toolbox onto your form.
Yet another possible workaround is to make the form and all of its children double-buffered. This doesn't speed up the painting at all but all of the windows get rendered into a memory buffer, the result is blitted to the screen. You'll notice a delay but the window suddenly pops on the screen. This is called compositing. Winforms doesn't support this directly since it can have side-effects but it is easy to enable. Paste this code into your form class:
Supported by XP and later. Watch out for painting artifacts.
或者您可以放弃标签并自己绘制文本:
or you can ditch the labels and draw the text yourself:
该标签不支持透明度,您必须创建自己独特的自定义控件,您可以查看这些代码示例。
http://www.codeproject.com/KB/dotnet/transparent_controls_net.aspx http://www.codeproject.com/KB/vb/uLabelX.aspx
再见
The label does not support transparency, you must create your own unique custom control, you can see these code examples.
http://www.codeproject.com/KB/dotnet/transparent_controls_net.aspx http://www.codeproject.com/KB/vb/uLabelX.aspx
Bye