Reputation: 9
I am looking to create a dynamic grid of picture boxes that will be generated once the user enters their desired number of rows and columns.
e.g. If user enters 3x3, 9 total picture boxes will be created in a grid like form.
Currently, my code will create all the desired picture boxes, but it will indent the first one in each new column creating an awkward shaped grid.
int rows = Convert.ToInt32(txtRow.Text);
int columns = Convert.ToInt32(txtColumn.Text);
// coordinates to place first box in the grid
int x = 211;
int y = 136;
int totalBoxes = rows * columns;
List<PictureBox> pictureBoxList = new List<PictureBox>();
for (int i = 0; i < totalBoxes; i++)
{
while (i < rows)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(70, 60),
Location = new Point(x, y),
BorderStyle = BorderStyle.Fixed3D,
SizeMode = PictureBoxSizeMode.Zoom,
Visible = true
};
this.Controls.Add(picture);
pictureBoxList.Add(picture);
y = y + 59;
break;
}
while (i < columns)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(70, 60),
Location = new Point(x, y),
BorderStyle = BorderStyle.Fixed3D,
SizeMode = PictureBoxSizeMode.Zoom,
Visible = true
};
this.Controls.Add(picture);
pictureBoxList.Add(picture);
x = x + 67;
break;
}
}
Upvotes: 0
Views: 1786
Reputation: 2120
You can use on cycle from 0 up to total picture box numbers, as you started in your code. In this case you should calculate position of each box, as Ashkan Mobayen Khiabani show you, like this:
// size of the boxes
Size size = new Size(70, 60);
int totalBoxes = rows * columns;
List<PictureBox> pictureBoxList = new List<PictureBox>();
for (int i = 0; i < totalBoxes; i++)
{
int curentColumn = i % columns;
int currentRow = i / columns;
int curentX = x + curentColumn * size.Width;
int curentY = y + currentRow * size.Height;
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = size,
Location = new Point(curentX, curentY),
BorderStyle = BorderStyle.Fixed3D,
SizeMode = PictureBoxSizeMode.Zoom,
Visible = true
};
this.Controls.Add(picture);
pictureBoxList.Add(picture);
}
However, you can also use two nested loops. First goes trough all the rows and second through all the columns, like this:
// size of the boxes
Size size = new Size(70, 60);
int totalBoxes = rows * columns;
List<PictureBox> pictureBoxList = new List<PictureBox>();
for (int row = 0; row < rows; row++)
{
int curentY = y + row * size.Height;
for (int col = 0; col < columns; col++)
{
int curentX = x + col * size.Width;
PictureBox picture = new PictureBox
{
Name = "pictureBox" + (row + col),
Size = size,
Location = new Point(curentX, curentY),
BorderStyle = BorderStyle.Fixed3D,
SizeMode = PictureBoxSizeMode.Zoom,
Visible = true
};
this.Controls.Add(picture);
pictureBoxList.Add(picture);
}
}
I personally prefer the nested loops way as it easier to read :)
From performance point of view both approaches should be the same.
Upvotes: 0
Reputation: 34170
you can set picturebox locations like this:
PictureBox picture = new PictureBox
{
Location = new Point(i%columns * desiredWidth, i/columns * desiredHeight),
....
};
for example as picturebox size is (70,60), with a 5 pixel more space between you may like it as new Point(i%columns * 75, i/columns * 65) //desiredWidth=75, desiredHeight=65
You may also give it an start Indent too:
Location = new Point(x+ i%columns * desiredWidth,y+ i/columns * desiredHeight);
I would do it like:
int w=75, h = 65;
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(70, 60),
Location = new Point(x + i%columns * w, y + i/columns * h),
BorderStyle = BorderStyle.Fixed3D,
SizeMode = PictureBoxSizeMode.Zoom,
Visible = true
};
Upvotes: 1