0

我有一个面板,上面有一个图片框。我必须在面板中显示大约 20 个标签。我希望标签的背景是透明的,即显示图片框中的图像,标签只显示文本。现在由于标签没有表现出真正的透明度,我将标签设置为图片框的子项

 this.lbl1.Parent = pictureBox1;

这解决了我的直接问题,但是现在当表单加载时,所有标签都需要一段时间才能变得可见,并且一次一个。如果你们能为此提供一些解决方案,我将不胜感激。

提前致谢

4

3 回答 3

4

闪烁的标准解决方法是双缓冲。但这并不能解决这种闪烁。它是一种不同的类型,是由多个窗口相互重叠引起的。每个标签都是它自己的窗口。当窗体需要自己绘制时,它会绘制其背景,为子窗口留下孔。然后每个子窗口轮流绘制自己。接下来他们的子窗口会自己绘制。等等。

当一个控件需要一段时间来绘制时,这会变得很明显,毫无疑问是你的图片框。特别是当它显示需要调整大小的大图像时。绘制图片框时,子窗口的孔保持未上漆。它们具有白色背景,当您使用表单的 TransparencyKey 或 Opacity 属性时为黑色。这可能与图片框中的图像形成鲜明对比,用户将这种效果视为闪烁。

一种直接的解决方法是不使用控件,这样您就不必为他们的窗口付费。Label 非常方便,但是仅仅为了显示一个字符串就烧掉一个窗口是对系统资源的巨大浪费。您可以简单地实现图片框的 Paint 事件并使用 TextRenderer.DrawText() 绘制字符串。PictureBox 默认开启双缓冲,因此图像和文本绘制完全流畅,不再闪烁。明显的缺点是你失去了点击的便利,你必须编写代码。

还有其他可能的修复。其中之一是防止图片框为子窗口留下孔。它将绘制整个图像,标签弹出在它们之上。这仍然闪烁,但几乎没有那么明显。在您的项目中添加一个新类并粘贴以下代码:

using System;
using System.Windows.Forms;

internal class MyPictureBox : PictureBox {
    protected override CreateParams CreateParams {
        get {
            var parms = base.CreateParams;
            parms.Style &= ~0x02000000;  // Turn off WS_CLIPCHILDREN
            return parms;
        }
    }
}

编译并将工具箱顶部的新图片框控件拖放到窗体上。

另一种可能的解决方法是使表单及其所有子级双缓冲。这根本不会加快绘制速度,但是所有窗口都被渲染到内存缓冲区中,结果被传送到屏幕上。您会注意到延迟,但窗口突然在屏幕上弹出。这称为合成。Winforms 不直接支持这一点,因为它可能有副作用,但很容易启用。将此代码粘贴到您的表单类中:

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

XP 及更高版本支持。注意绘画文物。

于 2011-07-08T13:18:29.440 回答
1

或者您可以放弃标签并自己绘制文本:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
  TextRenderer.DrawText(e.Graphics, "Label1", SystemFonts.DefaultFont,
                        new Point(10, 10), Color.Black, Color.Empty);
}
于 2011-07-08T12:59:42.797 回答
0

标签不支持透明,必须创建自己独特的自定义控件,可以看这些代码示例。

http://www.codeproject.com/KB/dotnet/transparent_controls_net.aspx http://www.codeproject.com/KB/vb/uLabelX.aspx

再见

于 2011-07-08T12:51:03.930 回答