Reputation: 255
I'm displaying in a panel PictureBox
overlapped, because each PictureBox
is used
as a layer. First time a PictureBox
is defined and added to panel it's background color
is transparent, and it's images are empty.
The problem is, the bottom layer can not be seen, the transparent image, shows the
panel's ground. Excepted is that the bottom PictureBox
's image is seen.
I have tried to it with other controls like label. The problem could not be solved :(
Thanks.
Upvotes: 5
Views: 17777
Reputation: 1294
I've been able to do this in VB. There are a couple of tricks though. First of all you have to add the picture boxes to each other. Second the images in the picture boxes have to be PNGs.
For this app I had to display 3 different layers on top of a background layer and turn them on and off with checkboxes. If it doesn't work, play around with how you save your PNGs, it's kind of picky about that.
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
Upvotes: 2
Reputation: 641
You should do
pe.Graphics.DrawImage(Image, 0, 0, Image.Width, Image.Height);
so your Image won't be streched
Upvotes: 0
Reputation: 8953
This is my take on it:
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;
}
}
}
You should add some more logic for positioning the image as you wish and edit the OnPaint method accordingly.
Upvotes: 6
Reputation: 5727
This is because, if I remember correctly, setting a background color of Transparent (its actual value is null, right?) isn't really transparent. What Windows does is it looks at the control's parent container's background color and sets the controls background color to that.
You can see this happen especially with panels. Without contents, panels set to Transparent should let you see behind them, right? Wrong. If you put a panel on top of a bunch of, say, textbox controls and set the panel to Transparent, you won't be able to see the textboxes behind it.
Instead, to get real transparency, you have to overload OnPaintBackground for the control in question and, essentially, do absolutely nothing (DONT'T call the base.OnPainBackground either!)... There's more to it than that, probably, but here is an example of a working TransparentPanel control we use here:
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
}
}
We've used this class successfully to create truly transparent panels in past Windows Forms apps. We used it as a hack to fix the "right-click context menu appears on top of button controls" problem.
Upvotes: 13