Can't set PictureBox location in panel - c#

I have a created a panel.
This has autoscroll = true
At the start i added 6 pictureboxes that are 256x256 with images.
I store the last picturebox location, so that i know where to put a new picturebox.
I also add a picturebox to the upper right of the panel(location(8744,8744)), so that the panel will stretch to 9000px.
Later on when i scroll around in the panel, i can push a button and add a picturebox to the panel. The problem is that when i set the location of the picturebox and add it to the panel, it comes out totally wrong, visually.
Code for adding more images.
private void addPictureBox(Point pixelCoordinates, Bitmap image)
{
PictureBox pNewImage = new PictureBox();
imagePanel.Controls.Add(pNewImage);
pNewImage.Image = image;
pNewImage.Name = "image_:" + pixelCoordinates.X + "_" + pixelCoordinates.Y;
pNewImage.Location = pixelCoordinates;
pNewImage.Size = new System.Drawing.Size(256, 256);
pNewImage.Visible = true;
pNewImage.BackColor = Color.White;
imagePanel.Update();
}
If i debug and watches the panel, it says that the new picturebox has the location i set, but visually, it's not.
I have noticed that this is what really happens:
The location of the picturebox is from where i have scrolled + location.X.
Anyone got an idea how i can fix this?
Thanks in advance.

If the pictureboxes are being added after you have scrolled away from the coordinates 0,0 you may need to account for this by adding the scroll amount to pixelCoordinates. Try using imagePanel.VerticalScroll.Value and imagePanel.HorizontalScroll.Value in your calculations.

Related

C#: create a stack of PictureBox

I have a background image, then I want to load several others on top of this. Each image is a png with an alpha channel that has different areas non-transparent.
I placed a PicureBox on a form. Then in the code:
private List<PictureBox> layers = new List<PictureBox>();
for (int l = 0; l < 11; l++)
{
Image i = (Image) Properties.Resources.ResourceManager.GetObject(l.ToString());
PictureBox b = new PictureBox
{
Parent = form_picture,
Image = i,
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.Zoom,
BackColor = Color.Transparent
};
//b.BringToFront();
layers.Add(b);
}
where "form_picture" is the PictureBox placed on the form, and my resource images are named 0,1,2..10.
It shows only the first image or the last one (removing the comment to the BringToFront method).
It doesn't seem a problem of transparency because I correctly see the background image, but only the first or last opaque area of the upper levels.
I'm afraid I'm not using correctly the properties.
IMO, you shouldn't use pictureboxes at all. They're too expensive for what You're trying to do. Use Graphics.DrawImage instead.
The System.Drawing.Image has a PixelFormat property of type System.Drawing.Imaging.PixelFormat that should help you with the alpha channel.

my png file is not showing in my picturebox

I want display an image in my picture box but when I run the code everything else works except the image isn't displayed. Here is the relevant code:
Image[] deadWoman = new Image[5]; //this array will hold the images of bit and pieces of katie
deadWoman[0] = Image.FromFile("F:/Jers Hangman Game/Jers Hangman Game/Resources/katie-hopkins.jpeg");
private void MainPic_Paint(object sender, PaintEventArgs e)
{
Graphics katie = e.Graphics; // creates a graphics object for the picture box
if (numWrongGuesses > 0)
{
e.Graphics.DrawImage(deadWoman[0], 20, 20,60,60);
}
}
I guess the image is never repainted, that's why you don't see it when numWrongGuesses is updated. You should Invalidate() the PictureBox in order to see the update.
I would advise to set the image though, and simply use Visible = true and Visible = false for showing and hiding. You could even set the BackgroundImage if you need to create some overlay effect.
You don't override Paint in order to put an Image object into a PictureBox. Just use the property:
MainPic.Image = deadWoman[0];
You can also do this in the WinForms designer, as long as the Image is a resource.
Also, you can hide and show your image by the .Visible property:
MainPic.Visible = numWrongGuesses > 0;

Best way to make images scrollable that where painted on the control

I draw images (lets say 200x200) on control in C# depending on how many there are (could be over 100) they get drawn offscreen since they are stacked one above the other. What is the best way to make a dynamic scroll so that i can scroll to the ones that are offscreen.
I was thinking of using a Panel and painting them on there and then just place the Panel on the control. But with the panel being transparent and the control on which the panel is sitting is changing its image (its a map that you can move with draging) the panel lags behind when drawing and creates a ugly jitter effect.
So are there any good solutions where i wont need to implement the whole logic of a scroller myself for such a solution?
PictureBox is doublebuffered and will take care of the flicker.
For your case don't draw onto a control, no matter which, but instead draw into a PictureBox's Image.
Put the PictureBox inside an autoscroll panel and make it a large as the Size you need. No jitter, smooth scrolling..
Here is an example. It randomly draws around 200 small images into the Image of a PictureBox. I create the Image with a large size and I put the PB into a Panel:
Random R = new Random();
private void button1_Click(object sender, EventArgs e)
{
panel1.AutoScroll = true;
pictureBox1.Parent = panel1;
pictureBox1.Location = Point.Empty;
pictureBox1.Image = new Bitmap(3000, 500);
pictureBox1.ClientSize = pictureBox1.Image.Size;
var imgFiles = Directory.GetFiles(#"D:\scrape\", "*.png");
foreach(string file in imgFiles)
{
using (Graphics G = Graphics.FromImage(pictureBox1.Image))
using (Bitmap bmp = new Bitmap(file))
{
if (bmp.Size.Width < 300)
{
for (int i = 0; i < 10; i++ )
G.DrawImage(bmp, R.Next(2500), R.Next(400));
}
}
}
}
You can easily adapt it to your own project, I'm sure..

How can i create a pictureBox manually to be exactly between two panels on form1?

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;

Create Objects in panel and arrange objects the new in first not in end

I want create manually PictureBox and Label on horizontal Panel, The count of PictureBox and Label on panel Unknown maybe 200 or more or less, I use the below code to do that but i face two troubles first one:
I want add the new object created in the first not in the end for example if i created items "A B C D E" want it add on Panel "E D C B A" want always the new come to first.
Note: Panel width "230" Height "710"
Second trouble:
Currently when i use Panel scroll bar to go down than add new objects find happen big free space between the last object created and the new and if i used scroll again to go down and created new object on panel happen more big free space.
int Right = 50, Top = 0;
// Create Image + Text
PictureBox pbox = new PictureBox();
pbox.Size = new Size(140, 80);
pbox.Location = new Point(Right, Top);
pbox.Image = Image.FromFile("");
Panel1.Controls.Add(pbox);
// Create label
Label lblPlateNOBAR = new System.Windows.Forms.Label();
lblPlateNOBAR.Text = lblPlateNO.Text;
lblPlateNOBAR.Location = new Point(Right + 20, Top + 80);
Panel1.Controls.Add(lblPlateNOBAR);
Top = Top + 150;
In order to make the objects insert into the panel, you'd need to move the controls which already exist in the panel:
int right = 50;
// Create Image + Text
PictureBox pbox = new PictureBox();
pbox.Size = new Size(140, 80);
pbox.Location = new Point(right, 0);
pbox.Image = Image.FromFile("");
// Create label
Label lblPlateNOBAR = new System.Windows.Forms.Label();
lblPlateNOBAR.Text = lblPlateNO.Text;
lblPlateNOBAR.Location = new Point(right + 20, 80);
foreach(var control in Panel1.Controls)
{
control.Top = control.Top + 150;
}
Panel1.Controls.Add(pbox);
Panel1.Controls.Add(lblPlateNOBAR);
I know it might seem that I'm not answering your question, but you can take little time to know my suggestion too. I don't know what you wanna achieve, but when you want to make such a sophisticated program, it's a better practice that you do all the work needed yourself, not relying on Windows Forms Controls. Trying to add, remove, change location of lots of controls will reduce the application performance very much. I suggest that you draw, for example your pictures, yourself, using Graphics and Image objects and Paint event. Also handle things like clicking and selecting pictures by MouseEvents. It might seem a little hard at first, but after you've done this you have far better performance and flexibility. This becomes more important considering you mentioned you wanna place 200 pictures in the panel. This also prevents trouble of flickering that appears when you change position of many controls. It's good to mention that to do scrolling in this case, you can place a Panel inside of a Parent Panel and use AutoScroll feature only for the parent panel to handle scrolling. This way you don't have to care about the scrolling anymore.

Categories