I need a little help understanding transparency order in windows forms. I created a simple form with nothing on it called test.
Within the construction of the form, I created a panel and a picture like so:
public partial class test : Form
{
public test()
{
InitializeComponent();
//create a panel
Panel panel = new Panel();
panel.Location = new Point(10, 10);
panel.Size = new Size(100, 100);
panel.BackColor = Color.FromArgb(255, 0, 0);
panel.Show();
//put panel on screen
this.Controls.Add(panel);
//create a picture box
PictureBox picture = new PictureBox();
picture.ImageLocation = "../myPicture2.png";
picture.Location = new Point(20, 20);
picture.Size = new Size(100, 100);
picture.BackColor = Color.Transparent;
picture.Show();
this.Controls.Add(picture);
picture.BringToFront();
}
}
At first the image I used was myPicture1.png, an image with a white background giving me this result.
But then I cropped out the white background with gimp to make it a transparent background.
However, now the form's background is showing up instead of panel.
When I'm putting this PictureBox on top of the panel I'm trying to keep the background color of the panel behind the Image.
Like this:
Can someone please explain to me how to acheive the desired result of having the panel background behind the transparent image in the picturebox? All advice is greatly appreciated as always!
Isn't this problem caused by the picturebox being on the form instead of being inside the panel?
panel.Controls.Add(picture);
Related
I want to place a Label on top of a gif inside a PictureBox in winforms.
The problem ist that the label has a white background. I want it to be transparent.
My Code is as follows:
this.pictureBox = new PictureBox();
this.pictureBox.Image = Image.FromFile("my_background.gif");
this.pictureBox.Dock = DockStyle.Fill;
this.pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
this.label = new Label();
this.label.Text = "Hallo";
this.label.BackColor = Color.Transparent;
this.label.Location = new System.Drawing.Point(100, 100);
this.Controls.Add(this.label);
this.Controls.Add(this.pictureBox);
My problem is that the Label has a white Background even though the background is set to transparent. The solution for other having a similar problem was setting the parent of the label to the picture Box like this:
this.label.parent = this.pictureBox;
But that didn't solve the problem for me. Is there any other way to achieve this?
Thanks for any answers.
Thanks for the hint.
It worked fine when putting only a view controls in front of the gif. When adding to many it got very buggy and only some rectangular parts of the gif would update.
I solved the problem by splitting my gif into single images and displaying them in the OnPaint Event of the form
this.Paint += new PaintEventHandler(this.Paint_Background);
The Paint Method looked like this.
private void Paint_Background(object sender, PaintEventArgs e)
{
Graphics background_graphics = e.Graphics;
Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
int image_num = ((int)((DateTime.Now - start_time).TotalMilliseconds) / gif_speed) % num_images;
Image background= Image.FromFile("Filename_"+image_num+".jpg");
background_graphics.DrawImage(background, 0, 0, ClientSize.Width, ClientSize.Height);
background.Dispose();
}
All of my Controls where added directly to the view and not the imagebox anymore, as the imagebox was removed entirely.
Maybe this can help someone else too
I have a PictureBox where I put some other controls (smaller PictureBoxes, labels..).
PictureBox pictureBox = new PictureBox();
pictureBox.Size = new Size(Width, Height);
pictureBox.Location = new Point(0, 0);
pictureBox.BackColor = Color.Transparent;
pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
// add child controls
PictureBox iconPictureBox = new PictureBox();
iconPictureBox.Location = new Point(icon.x, icon.y);
iconPictureBox.Size = new Size(icon.width, icon.height);
iconPictureBox.BackColor = Color.Transparent;
iconPictureBox.Image = Image.FromFile(resourcesPath);
iconPictureBox.Click += IconPictureBox_Click;
pictureBox.Controls.Add(iconPictureBox);
When I tried to attach the main picture box "pictureBox" to the MainForm window using Controls.Add, after setting the new size and position of the picture box, it is drawn in the correct place with correct size but the contents are not stretched i.e. their positions are not changed.
Is there a method to make the related controls stretched within the main pictureBox?
The scale method of the forms container (PictureBox or Panel) can be used to resize it, all child forms should have the SizeMode to stretch so that they will follow the scaling.
i am currently trying to put the notes on top of the staff image. However, the notes background are being set to the form background as shown in the image.
image type used is png.
//class music staff
public MusicStaff(int xLoc, int yLoc, int xSize, int ySize)
{
this.SetBounds(xLoc, yLoc, xSize, ySize);
this.Visible = true;
ResourceManager rm = Resources.ResourceManager;
Bitmap bmp = (Bitmap)rm.GetObject("Staff1");
this.BackgroundImage = bmp;
this.BackgroundImageLayout = ImageLayout.Stretch;
this.BackColor = Color.White;
//adding the background pic
panel4 = new MusicStaff(3, 62, 927, 150);
//adding a note
MusicNote p = new MusicNote(pitch, duration, shape, s);
p.SizeMode = PictureBoxSizeMode.StretchImage;
p.BackColor = Color.Transparent;
p.Size = new Size(50, 75);
p.Location = new Point(xCounter + starterX, NoteLocations.c0.mainPoint);
Bitmap myImage = (Bitmap)rm.GetObject(shape);
p.Image = myImage;
You are not really overlaying images. You are overlaying controls with images.
For this to work with transparency, your notes controls need to be nested in the staff control!
As they aren't, the transparency shows the color of their actualy parent, i.e. the form.
Set p.Parent=panel4 and adapt the locations accordingly, i.e. make them relative to the staff..
This is a limitation of winforms transparency, which doesn't support overlapping controls. Nested controls will work fine but only by faking the transparent parts by copying them from the parent..
Note that as a consequence you will not be able to have the notes overlap each other or be overlapped by any other controls.
Often giving up on using controls is the better way; instead one can simply draw all parts that make up the total..
So you could do a series of e.Graphics.DrawImage(noteImg, x, y) in the panel4_Paint event.
I have added two custom controls in the form as one control placed over the another control. Set the backcolor as trasparent for control1 but it shows the back color as form color instead of underlying control(control2) color. Please share your ideas . Thanks in advance.
Note : For example i have mentioned as picturebox but same problem raises for any controls such as richtextbox or placing the custom controls.
Image link : IssueImage
private void InitializeComponent()
{
#region picturebox
this.BackColor = Color.Aquamarine;
this.WindowState = FormWindowState.Normal;
var selectBtn = new Button();
selectBtn.Size = new Size(100, 30);
selectBtn.Location = new Point(10, 10);
selectBtn.Text = "Click";
//selectBtn.Click += selectBtn_Click;
var picturebox = new PictureBox();
picturebox.Size = new Size(140, 110);
picturebox.Location = new Point(4, 4);
picturebox.SizeMode = PictureBoxSizeMode.StretchImage;
picturebox.Image = new Bitmap(#"..\..\Data\graphic1.png");
var picturebox2 = new PictureBox();
picturebox2.Size = new Size(140, 110);
picturebox2.Location = new Point(4, 4);
picturebox2.SizeMode = PictureBoxSizeMode.StretchImage;
picturebox2.Image = new Bitmap(#"..\..\Data\graphic1.png");
graphiccell = new GraphicCellControl();
graphiccell.Location = new Point(50, 200);
graphiccell.BackColor = Color.Transparent;
graphiccell.Size = new Size(160, 130);
var graphiccell2 = new GraphicCellControl();
graphiccell2.Location = new Point(100, 250);
graphiccell2.BackColor = Color.Red;
graphiccell2.Size = new Size(160, 130);
// graphiccell2.BackColor = Color.Transparent;
graphiccell.Controls.Add(picturebox);
graphiccell2.Controls.Add(picturebox2);
this.Controls.Add(graphiccell);
this.Controls.Add(graphiccell2);
this.Controls.Add(selectBtn);
#endregion
}
public class GraphicCellControl : Control
{
public GraphicCellControl()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
}
Transparency in Windows Forms follows the rules for Windows windows (ugh). This means that by default, you only get "proper" transparency when you're dealing with the parent-child relationship. Controls behind a transparent control will only be drawn if they are parents of said transparent control.
If this isn't feasible for you for some reason, you can always override the OnPaint or OnPaintBackground methods, and explicitly render whatever control you need to render regardless of the parent-child relationship. Of course, you'll quickly find why this isn't done by default if you can't do a few simplifying assumptions :)
As a quick list of what you need to do when there aren't any simplifications possible:
Find controls that are behind the transparent control - this is especially tricky when there isn't any spatial partitioning (like the mentioned parent-child relationship)
Render the relevant surfaces of the controls from 1. in back to front order on the current control's surface
Optimally, ensure that all the overlapping transparent controls avoid rendering the same controls multiple times
Ensure that all operations that can potentially change the background of the transparent control cause an invalidation (and thus re-render) of the transparent control's background
I created an array of PictureBox objects in my code like so:
PictureBox[] picturbox = new PictureBox[100];
Then I have this in Form's load code:
picturbox[1] = new PictureBox();
picturbox[1].Image = Properties.Resources.img1;
picturbox[1].Visible = true;
picturbox[1].Location = new Point(0, 0);
this.Size = new Size(800, 600);
picturbox[1].Size = new Size(800, 600);
However, the PictureBox does not appear on the Form. When I do exact same command with PictureBox that was created by Drag & Drop, it works just fine.
You need to add the pictureBox to the Form:
this.Controls.Add(picturebox[1]);
You need to add each PictureBox to the form's Controls.
foreach(var box in picturbox)
this.Controls.Add(box)
If you did not add picture box, check the InitializeComponent(); method. It is positioned at the top of the code.
This works just as well:
this.Controls.AddRange(picturebox);
For a collection that isn't an array use this:
this.Controls.AddRange(picturebox.ToArray());