I have a simple form with 10 picture boxes like: pictureBox1, pictureBox2, pictureBox3...
And I have a folder with 10 images like: image1, image2, image3...
Now I am smart enough to know that I don't want to hard code pictureBox1.ImageLocation = image1, pictureBox2.ImageLocation = image2... Rather, I need to create some kind of loop or array that will populate my picture boxes with their respective images, but I am not smart enough to figure out how.
Something like:
for (int i = 0; i < 10; i++)
{
pictureBox[i].ImageLocation = image[i];
}
Eventually, I was hoping this project would scale dynamically, if I have a file with say 12 images, the program will simply create 12 picture boxes and load the images. A little help would be great.
What you have there would roughty work though I would suggest a list.
List<PictureBox> pictureBoxes = new List<PictureBox>();
List<Image> images = new List<Image>();
//code to populate your lists
for (int i = 0; i < pictureBoxes.Count; i++)
{
pictureBoxes[i].Image = images[i];
}
If you want to make sure you have enough images for your PictureBox list you could check ahead of time:
if (images.Count >= pictureBoxes.Count)
{
for (int i = 0; i < pictureBoxes.Count; i++)
{
pictureBoxes[i].Image = images[i];
}
}
...or fill out as many as you can before running out of images.
for (int i = 0; i < pictureBoxes.Count && i < images.Count; i++)
{
pictureBoxes[i].Image = images[i];
}
EDIT:
So if you want to use strings to set the location of the images instead you can do that. Check this out:
List<PictureBox> pictureBoxes = new List<PictureBox>();
List<string> imageLocations = new List<string>();
private void Form1_Load(object sender, EventArgs e)
{
PictureBox PB1 = new PictureBox();
PB1.Location = new Point(0, 0);
PB1.Size = new Size(144, 197);
Controls.Add(PB1);
PictureBox PB2 = new PictureBox();
PB2.Location = new Point(145, 0);
PB2.Size = new Size(327, 250);
Controls.Add(PB2);
pictureBoxes.Add(PB1);
pictureBoxes.Add(PB2);
imageLocations.Add(#"C:\PicExample\image1.jpg");
imageLocations.Add(#"C:\PicExample\image2.jpg");
for (int i = 0; i < pictureBoxes.Count && i < imageLocations.Count; i++)
{
pictureBoxes[i].ImageLocation = imageLocations[i];
}
}
EDIT for Iteratively Creating PictureBoxe List:
If you want to not have to worry about hard-coding your list (and your picture boxes will be the same size) you could do something like this:
for (int i = 0; i < HoweverManyPictureBoxesYouWant; i++)
{
PictureBox PB = new PictureBox();
PB.Name = "PB" + i.ToString();
PB.Location = new Point(250 * i, 0); //Edit this as you see fit for location, i'm just putting them in a row
PB.Size = new Size(250, 250);
PB.ImageLocation = #"C:\PicExample\image" + i.ToString() + ".jpg";
Controls.Add(PB);
pictureBoxes.Add(PB); //You only need to do this if you want the PB's in a list for other reasons than setting the image location
}
Related
I am loading images like this:
image = Image.FromFile(//here goes path to image);
Than i have list of pictureBoxes like this
List<PictureBox> pictureBoxes = new List<PictureBox>();
Than i load picture boxes in pictureBox list like this
// i is set to one
for (; i < this.images.Count; i++)
{
pictureBoxes.Add((PictureBox)Controls.Find("pictureBox" + i.ToString(), true)[0]);
}
And now I want to load that image in pictureBox[0]. Then I load another image and I want to add it to pictureBox[1] and so on. I am trying to do this more than 3 days. Does anyone know how to do it?
After you filled your picturebox list, just find the first empty one.
var emptyPb = pictureBoxes.Where(x => x.Image == null).FirstOrDefault();
if(emptyPb==null)
{
throw new Exception("No empty picturebox could be found!");
return;
}
emptyPb.Image = images[0];
//Set the number of images you have.
int imageCount = 3;
//Create path.
string path = #"C:\ImageFolder\";
//Create the List of PictureBox
List<PictureBox> pictureBoxes = new List<PictureBox>();
//This for will create the name foreach image.
//Example: "pic1", "pic2", "pic3".
//Assuming that you have the names of each file image like the example.
for (int i = 1; i < imageCount + 1; i++)
{
//Create a PictureBox foreach image
PictureBox pictureBox = new PictureBox()
{
Name = $"pic{i}",
//Assign the image file.
Image = Image.FromFile(path + $"pic{i}.jpg")
};
//Add the new pictureBox to the list pictureBoxes
pictureBoxes.Add(pictureBox);
}
I'm trying to make the game 2048 in C#, but I have a problem when I move the tiles.
Here is where I keep the tiles:
picture = new PictureBox[4, 4] {
{pic1,pic2,pic3,pic4},
{pic5,pic6,pic7,pic8},
{pic9,pic10,pic11,pic12},
{pic13,pic14,pic15,pic16} };
And when I press 'W' I move it up :
public void Up()
{
for (int i = 1; i < picture.GetLength(0); i++)
for (int j = 0; j < picture.GetLength(1); j++)
if(picture[i,j].Image!=null && picture[i-1,j].Image==null)
{
picture[i - 1, j].Image = picture[i, j].Image;
picture[i, j].Image = null;
Up();
}
}
but that code only interchanges images from picturebox not the picturebox itself. How can I interchange the picturebox with image and all its property ?
There is no switching functionality in C#, so you will need a temporary helper variable.
It is up to you to decide what you want to switch:
the pictureBoxes referenced in your array
just their locations
their images
or any combination..
Here is an example of a simple helper function that exchanges the references and their Locations:
void SwitchControls(PictureBox pb1, PictureBox pb2)
{
PictureBox temp = pb1;
Point tempLoc = pb1.Location;
pb1 = pb2;
pb2 = temp;
pb1.Location = pb2.Location;
pb2.Location = tempLoc ;
}
You would call it for example like this:
SwitchControls(picture[i - 1, j], picture[i, j]);
To exchange the Images you would write the function as
void SwitchImages(PictureBox pb1, PictureBox pb2)
{
Image temp = pb1.Image;
pb1.Image = pb2.Image;
pb2.Image = temp.Image;
}
etc..
Ok so I decided to add controls to a panel on form_load based on labels in an array. Below is my code, but no matter how many files I upload through the button listener and reload this form, it only displays one label and nothing more. Why is it only displaying one? I have added a breakpoint and verified that the count does go up to 2, 3, etc.
Code:
public partial class Attachments : Form
{
ArrayList attachmentFiles;
ArrayList attachmentNames;
public Attachments(ArrayList attachments, ArrayList attachmentFileNames)
{
InitializeComponent();
attachmentFiles = attachments;
attachmentNames = attachmentFileNames;
}
private void Attachments_Load(object sender, EventArgs e)
{
ScrollBar vScrollBar1 = new VScrollBar();
vScrollBar1.Dock = DockStyle.Right;
vScrollBar1.Scroll += (sender2, e2) => { pnl_Attachments.VerticalScroll.Value = vScrollBar1.Value; };
pnl_Attachments.Controls.Add(vScrollBar1);
Label fileName;
for (int i = 0; i < attachmentNames.Count; i++)
{
fileName = new Label();
fileName.Text = attachmentNames[i].ToString();
pnl_Attachments.Controls.Add(fileName);
}
}
private void btn_AddAttachment_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string fileName = openFileDialog1.FileName;
attachmentFiles.Add(fileName);
attachmentNames.Add(Path.GetFileName(fileName));
this.Close();
}
}
}
This is because the labels are all stacking on top of each other. You will need to specify a top for each one or use an auto-flow panel.
Adding the following line after creating the new label will ensure all labels are visible (you may have to adjust the multiplier depending on your font):
fileName.Top = (i + 1) * 22;
As competent_tech stated the labels are stacking on top of each other, but another approach is to modify the location value of the label.The benefit to this is you can control the absolute location of the label.
fileName.Location = new Point(x, y);
y += marginAmount;
x is the vertical position on the form and y is the horizontal location on the form. Then all that has to be modified is the amount of space you want in between each label in the marginAmount variable.
So in this for loop
for (int i = 0; i < attachmentNames.Count; i++)
{
fileName = new Label();
fileName.Text = attachmentNames[i].ToString();
pnl_Attachments.Controls.Add(fileName);
}
You could modify it to this:
for (int i = 0; i < attachmentNames.Count; i++)
{
fileName = new Label();
fileName.Text = attachmentNames[i].ToString();
fileName.Location = new Point(x, y);
y += marginAmount;
pnl_Attachments.Controls.Add(fileName);
}
Then all you have to do is define x, y, and the marginAmount.
I am trying to show images in a row..For this I am trying to add picture boxes dynamically. Image location is stored in databses. my code is as
int iCtr = 0;
for (int i = 0; i < dt.Rows.Count; i++)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox"+i,
Size = new Size(316, 320),
Location = new Point(1, iCtr * 1100 + 1),
Visible = true
};
// string fname = dt.Rows[2]["FileName"].ToString();
picture.ImageLocation = dt.Rows[i]["FileName"].ToString();
//#"..\Images\80knhk00003.jpg";
pnlDisplayImage.Controls.Add(picture);
iCtr++;
}
where dt is datable.
with this I can see only last image but not all images. Even last image is very small and complete image is not shown.(i.e. I can view only one corner of actual image).
How can I give size to image so that it can be viewed completely?
And how can I display images in row?
Please help
Thanks
Can you try something like this? To get the scaling, see PictureBoxSizeMode.
List<PictureBox> pictureBoxList = new List<PictureBox>();
for (int i = 0; i < dt.Rows.Count; i++)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(316, 320),
Location = new Point(i * 316, 1),
BorderStyle = BorderStyle.FixedSingle,
SizeMode = PictureBoxSizeMode.Zoom
};
picture.ImageLocation = dt.Rows[i]["FileName"].ToString();
pictureBoxList.Add(picture);
}
foreach (PictureBox p in pictureBoxList)
{
pnlDisplayImage.Controls.Add(p);
}
instead of Image property, set the BackGroundImage property to your picture location, and then set the BackGroundImageLayout to the value "Stretch" then you will see full image.
I am trying to draw lots of instances of an image using the following code:
PictureBox[] sprites = new PictureBox[100];
private void Game_Load(object sender, EventArgs e)
{
PictureBox mainSprite = new PictureBox();
Bitmap img = new Bitmap(SpriteTest.Properties.Resources.Image); //Load a png image
mainSprite.Size = new Size(16, 16);
mainSprite.Image = img;
for(var i = 0; i < sprites.Length; i++)
{
sprites[i] = mainSprite;
//Keeping it simple for now with a single row of sprites
sprites[i].Location = new Point(i * 16, 8);
}
Game.ActiveForm.Controls.AddRange(sprites);
}
When it comes to running the code, only the last image is shown. While debugging the code, everything seems to be working as expected. I can also verify that the location is in fact being updated.
I have also tried adding the controls differently using the following code in the for loop (with no luck);
this.Controls.Add(sprites[i]);
I have had this problem many times, especially when I tried to create many GroupBoxes in a similar fashion. For the hours that I searched online as I tried to find a solution, nothing has ever fixed it.
You're only actually creating one instance of PictureBox:
PictureBox mainSprite = new PictureBox();
...
for(var i = 0; i < sprites.Length; i++)
{
sprites[i] = mainSprite;
Your array will have lots of reference to the same object. You should create a new PictureBox on each iteration of the loop:
for(var i = 0; i < sprites.Length; i++)
{
PictureBox mainSprite = new PictureBox();
mainSprite.Size = new Size(16, 16);
mainSprite.Image = img;
sprites[i] = mainSprite;
...
}