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.
Related
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);
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
On my form i have a PictureBox inside Panel.
I set:
MyPanel.AutoScroll = true
MyPictureBox.SizeMode = AutoSize
After i add image into PictureBox:
MyPictureBox.Image = Image.FromFile(path);
But when i open form i don't see any scrollbars inside.
What can be wrong?
You have to probably set height and width of PictureBox and set AutoScroll property of Panel to true.
Panel MyPanel = new Panel();
PictureBox pictureBox1 = new PictureBox();
Image image = Image.FromFile("image.png");
pictureBox1.Image = image;
pictureBox1.Height = image.Height;
pictureBox1.Width = image.Width;
MyPanel.Controls.Add(pictureBox1);
MyPanel.AutoScroll = true;
this.Controls.Add(MyPanel);
Try
MyPanel.ScrollBars = ScrollBars.Auto
Tips:
Verify that MyPictureBox is inside MyPanel, in other words, MyPanel contains MyPictureBox.
On the Designer, make MyPictureBox significantly smaller than its container MyPanel. Due to AutoSize, it will fill the entire space provided by the container during runtime.
Check that MyPictureBox has property Anchor set to Top, Left but NOT Top, Left, Bottom, Right.
My form1 size is 800,600
Then i have two panels in the form1 designer:
Panel1 is at location: 0,24 size: 200,437
Panel2 is at location: 584,24 size: 200,437
The result is two panels at each side of the form.
Now i did in my program when you put the mouse somewhere in the form1 area its showing a pictureBox i create in the form1 constructor:
pb = new AnimatedPictureBox.AnimatedPictureBoxs();
pb.Visible = false;
pb.Size = new Size(500, 350);
pb.Location = new Point((ClientSize.Width - pb.Width) / 2,
(ClientSize.Height - pb.Height) / 2);
The problem is that the new pictureBox variable pb is not in the size that will fill all the area between the two panels.
I want the size of the pictureBox to fill almost all the space between the two panels Width and Height maybe to leave some space like 5 spaces each side so there will be a border.
How can i calculate what the pictureBox size should be ?
EDIT**
This is an image where the program is working regular. On each panel on the left and right i added 4 pictureBoxes.
When i move my mouse cursor inside one of the pictureBoxes area its showing its content in a larger pictureBox in the middle.
And this is how it looks like when i put the mouse cursor in one of the pictureBoxes area the pictureBox in the middle is not big enough its Width and Height dosent make the big pictureBox to be excatly between the two panels. The big pictureBox not high and not wide enough.
if you want to make your layout stable even after resizing you should use Dock property for your panels and set Anchor for your picture box. Like that:
panel1.Dock = DockStyle.Left;
panel2.Dock = DockStyle.Right;
pb.Anchor = AnchorStyles.Left | AnchorStyles.Right;
And in general to place it in the center you can use something like that:
var width = this.Width - panel1.Width - panel1.Margin.Horizontal
- panel2.Width - panel2.Margin.Horizontal;
pb.Size = new Size(width, 300); // put your needed height here
pb.Top = this.Height/2 - pb.Height/ 2;
pb.Left = panel2.Left + panel2.Width + panel2.Margin.Right;