C#重叠PictureBox的透明度问题

时间:2009-08-05 18:40:45

标签: c# winforms transparency

我在重叠的面板PictureBox中显示,因为使用了每个PictureBox 作为一个层。第一次定义PictureBox并将其添加到面板时它的背景颜色 是透明的,它的图像是空的。

问题是,底层无法看到,透明图像显示出来 小组的理由。例外情况是看到底部PictureBox的图像。

我已尝试过像label这样的其他控件。问题无法解决:(

感谢。

4 个答案:

答案 0 :(得分:11)

这是因为,如果我没记错的话,设置Transparent的背景颜色(它的实际值为null,对吧?)不是真的透明。 Windows的作用是查看控件的父容器的背景颜色,并将控件背景颜色设置为该颜色。

你可以看到这种情况发生在面板上。没有内容,设置为透明的面板应该让你看到它们后面,对吗?错误。如果您将一个面板放在一堆文本框控件上并将面板设置为透明,您将无法看到它背后的文本框。

相反,要获得真正的透明度,你必须为相关控件重载OnPaintBackground,基本上,什么都不做(不要把base.OnPainBackground调用!)......还有更多的东西,可能,但这里是我们在这里使用的一个工作的TransparentPanel控件的例子:

public class TransparentPanel : System.Windows.Forms.Panel
{
    [Browsable(false)]
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }
    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // Do Nothing
    }
}

我们已成功使用此类在过去的Windows窗体应用程序中创建真正透明的面板。我们用它来修复“右键单击上下文菜单出现在按钮控件之上”的问题。

答案 1 :(得分:5)

这是我的看法:

class TransPictureBox : Control
{
    private Image _image = null;

    public Image Image
    {
        get
        {
            return _image;
        }
        set
        {
            _image = value;
        }
    }
    public TransPictureBox()
    {
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        if(Image != null)
            pe.Graphics.DrawImage(Image, 0, 0);
    }
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }
}

您应该根据需要添加一些用于定位图像的逻辑,并相应地编辑OnPaint方法。

答案 2 :(得分:2)

我已经能够在VB中执行此操作。虽然有几个技巧。首先,你必须互相添加图片框。其次,图片框中的图像必须是PNG。

对于这个应用程序,我必须在背景图层上显示3个不同的图层,然后使用复选框打开和关闭它们。如果它不起作用,请玩你如何保存你的PNG,这有点挑剔。

Imports System.Drawing
Imports System.Drawing.Imaging
Imports System

Public Class Form1

    Dim MarkerBox1 As New PictureBox
    Dim MarkerBox2 As New PictureBox
    Dim MarkerBox3 As New PictureBox

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        PictureBox1.Image = New Bitmap("C:\BackGround.bmp")

        MarkerBox1.Image = New Bitmap("C:\TestOverlay1.png")
        MarkerBox1.BackColor = System.Drawing.Color.Transparent
        MarkerBox1.Visible = True
        MarkerBox1.SizeMode = PictureBoxSizeMode.AutoSize
        PictureBox1.Controls.Add(MarkerBox1)

        MarkerBox2.Image = New Bitmap("C:\TestOverlay2.png")
        MarkerBox2.BackColor = System.Drawing.Color.Transparent
        MarkerBox2.Visible = True
        MarkerBox2.SizeMode = PictureBoxSizeMode.AutoSize
        MarkerBox1.Controls.Add(MarkerBox2)

        MarkerBox3.Image = New Bitmap("C:\TestOverlay3.png")
        MarkerBox3.BackColor = System.Drawing.Color.Transparent
        MarkerBox3.Visible = True
        MarkerBox3.SizeMode = PictureBoxSizeMode.AutoSize
        MarkerBox2.Controls.Add(MarkerBox3)


    End Sub

    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
        If CheckBox1.Checked Then
            MarkerBox1.Visible = True
        Else
            MarkerBox1.Visible = False
        End If
        Visibilitychanged()
    End Sub

    Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
        If CheckBox2.Checked Then
            MarkerBox2.Visible = True
        Else
            MarkerBox2.Visible = False
        End If
        Visibilitychanged()
    End Sub

    Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged
        If CheckBox3.Checked Then
            MarkerBox3.Visible = True
        Else
            MarkerBox3.Visible = False
        End If
        Visibilitychanged()
    End Sub

    Private Sub Visibilitychanged()

        PictureBox1.Controls.Clear()
        MarkerBox1.Controls.Clear()
        MarkerBox2.Controls.Clear()
        MarkerBox3.Controls.Clear()

        Dim PB As PictureBox = PictureBox1
        If MarkerBox1.Visible Then
            PB.Controls.Add(MarkerBox1)
            PB = MarkerBox1
        End If
        If MarkerBox2.Visible Then
            PB.Controls.Add(MarkerBox2)
            PB = MarkerBox2
        End If
        If MarkerBox3.Visible Then
            PB.Controls.Add(MarkerBox3)
            PB = MarkerBox3
        End If

    End Sub

答案 3 :(得分:0)

你应该做

pe.Graphics.DrawImage(Image, 0, 0, Image.Width, Image.Height);

所以你的影像不能被拉伸