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.
Related
My code in C# displays picture boxes vertically where the second picture box is below the first one instead of displaying the second picture box horizontally next to the first such that when the width of the visible form overflows. the code creates a new row and continues to create picture boxes. The code reads image file paths from a folder and initializes an array of picture boxes based on the count of the images. The goal is to create a grid of picture boxes for displaying the images. How can I update the logic of the app to make it achieve the desired output.
public class ImageGrid:Form {
//declare the folder name that contains the complex images
private string _folder = "./Complex"; //declare the array of picture boxes to display in the form
private PictureBox[] _image_grid;
private List<string> _paths= new List<string>();
public ImageGrid() {
//set a title for the form
Text = "Confidence Level Checker";
//make the screen full
FormBorderStyle =
FormBorderStyle.None;
WindowState =
FormWindowState.Maximized;
//read all the image names in the folder
if (Directory.Exists(_folder)) {
//list all the files in the folder
string[] files =
Directory.GetFiles(_folder);
if (files != null && files.Length > 0) {
//add the paths to the list
foreach (var path in files) {
_paths.Add(path);
}
//create an array of picture boxes based on the file count
_image_grid = new PictureBox[files.Length];
//declare the size of each picture box
int width = 300; int height = 250;
int x = 20; int y = 20;
foreach (string path in _paths) {
PictureBox box = new PictureBox()
{
Size = new Size(width, height),
Location = new Point(x,y),
Image = Image.FromFile(path),
SizeMode = PictureBoxSizeMode.StretchImage
};
//add the picture box to the form
this.Controls.Add(box);
//update the location to draw the picture box
x += 320;
if (x + 300 > ClientSize.Width) { x = 20; y += 270; }
}
}
}
}
You can use a FlowLayoutPanel() instead to make this simpler.
Then ensure (in the form designer) that the property FlowDirection is set to LeftToRight.
You can also do this in code:
myFlowLayoutPanel.FlowDirection = FlowDirection.LeftToRight;
You add controls to a FlowLayoutPanel the same way you do to a standard Panel:
myFlowLayoutPanel.Add(someControl);
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 am adding 8 panels to a "flowLayoutPanel1". It works fine.
The problem is that it comes 4 panels on the first"row" and then 4 panels on next "row".
The thing is that I have made the size of the "flowLayoutPanel1" to visually show 3 panels on each "row", - so in this case, half of the 4th panel on each row are not seen.
But if I add them in the designer manually, it do come 3 panels on each "row" which I want.
I wonder why this is happening when I add them dynamically with this code?
flowLayoutPanel1.Controls.Clear(); int count = 0;
for (int n = 0; n < 4; n++)
{
for (int i = 0; i < latestImageLIST.Count; i++)
{
//Now add all images as panels
String imagefile = latestImageLIST[i];
if (File.Exists(imagefile))
{
Panel panel = new Panel(); count++;
panel.Name = "thepanel" + count;
panel.Size = new Size(284, 160);
panel.Margin = new Padding(3);
Image image = Image.FromFile(imagefile);
panel.BackgroundImage = image;
panel.BackgroundImageLayout = ImageLayout.Stretch;
panel.Tag = "thepanel" + count;
panel.Click += new System.EventHandler(this.panel216_Click);
flowLayoutPanel1.Controls.Add(panel);
}
}
}
I recommend using TableLayoutPanel, which is an alternative to FlowLayoutPanel. You can first determine the row and column based on the number of images you need to load, then dynamically create a Panel through a loop and add it to the specified row and column.
public void AddImages(int row, int col)
{
TableLayoutPanel tlp = new TableLayoutPanel();
int prow = 100 / row, pcol = 100 / col;
for(var i=0;i<row;i++)
{
tlp.RowStyles.Add(new RowStyle(SizeType.Percent, prow));
}
for(var i=0;i<col;i++)
{
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, pcol));
}
//modify the add logic according to your requirement.
tlp.Controls.Add(new Panel() { Dock = DockStyle.Fill }, 1, 1);
//todo...
this.Controls.Add(tlp);
}
How to get picture box image at right side in TableLayoutPanel in c#? At present i am getting two images besides but i don't need. i need only one image to their at extreme right side and i need to remove space between two rows
for (int i = 0, r = 0; i < dt.Rows.Count; i++, r++)
{
PictureBox pb = new PictureBox();
pb.ImageLocation = ../imagesDT/answered.gif
tableLayoutPanel1.Controls.Add(pb);
}
Below is my attached image i am getting issue as described above.
You need to set the Column and the Row those PictureBoxes shall sit in:
for (int i = 0, r = 0; i < dt.Rows.Count; i++, r++)
{
int maxCol = tableLayoutPanel1.ColumnCount - 1;
PictureBox pb = new PictureBox();
pb.ImageLocation = ../imagesDT/answered.gif
tableLayoutPanel1.Controls.Add(pb);
tableLayoutPanel1.SetRow(pb, i);
tableLayoutPanel1.SetColumn(pb, maxCol );
}
You can get the columns' Widths and the rows' Heights like this:
var widths = tableLayoutPanel1.GetColumnWidths();
var heights = tableLayoutPanel1.GetRowHeights();
You can fine-tune the position by setting Margins, e.g.:
pb.Margin = New Padding(50, 20, 0, 0);
To change the Heights of the Rows you can either use the Designer or you'll can set its Height in the RowStyle of each Row:
tableLayoutPanel1.RowStyles[row].SizeType = SizeType.Absolute;
tableLayoutPanel1.RowStyles[row].Height = newHeight;
To make your table layout visible during your tests you may want to insert code like this in the CellPaint event:
private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
Random R = new Random(1 + e.Row * 3 + e.Column * 7);
using (SolidBrush brush = new SolidBrush(
Color.FromArgb(99, Color.FromArgb( R.Next(123456789)))))
e.Graphics.FillRectangle(brush, e.CellBounds);
}
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
}