How to assign the name of pictureBox in foreach loop - c#

I have tried using Tag, Name, Text, IndexOf. Every time, I get the first name and that's it. Here is the code:
// Perform scanning
for (;;)
{
List<System.Drawing.Image> images = this.ScannerDevice.PerformScan().ToList();
// Show picture in window
this.Invoke((MethodInvoker)delegate
{
this.FrontImage = images[0];
foreach (System.Drawing.Image image in images)
{
PictureBox pf = new PictureBox();
pf.SizeMode = PictureBoxSizeMode.StretchImage; pf.Height = 150; pf.Width = 170;
pf.Image = image;
pf.Click += new EventHandler(pictureClicked);
flowLayoutPanel1.Controls.Add(pf);
pf.Tag=flowLayoutPanel1.Controls.Count;
}
ScanFinishedEventArgs eventArgs = new ScanFinishedEventArgs { AcceptScan = true };
this.ScanFinished?.Invoke(this, eventArgs);
label1.Text = Convert.ToString(flowLayoutPanel1.Controls.Count);
});
}
void pictureClicked(object sender, EventArgs e)
{
if (selectedPicture != null)
selectedPicture.BorderStyle = BorderStyle.None;
selectedPicture = (PictureBox)sender;
selectedPicture.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.Image = selectedPicture.Image;
label2.Text = Convert.ToString(pf.Tag);
}
Also I would like to use that name later to be displayed in another label when I click on the certain picturebox.
Also I have tried using anonymous types but unable to use it with image objects. What am I doing wrong?

I've just done this and it seems to work. 3 images are added, each named according to the index value at the time. A label is set showing the image count. The picture clicked handler displays the name in a message box when the image is clicked.
private void button1_Click(object sender, EventArgs e)
{
int index = 0;
foreach (Image image in images.Images)
{
PictureBox pf = new PictureBox();
pf.SizeMode = PictureBoxSizeMode.StretchImage;
pf.Height = 50;
pf.Width = 50;
pf.Click += new EventHandler(PictureClicked);
pf.Name = index.ToString();
pf.Image = image;
flowLayoutPanel1.Controls.Add(pf);
index++;
}
lblImagecount.Text = index.ToString();
}
private void PictureClicked(object sender, EventArgs e)
{
MessageBox.Show(((PictureBox) sender).Name);
}

Related

c# Picturebox Array Selection

I have created an array of picture boxes and an event for when one is clicked.
public void TicTac_Load(object sender, EventArgs e)
{
PictureBox[] PBox = new PictureBox[9];
PBox[0] = this.pictureBox1;
PBox[1] = this.pictureBox2;
PBox[2] = this.pictureBox3;
PBox[3] = this.pictureBox4;
PBox[4] = this.pictureBox5;
PBox[5] = this.pictureBox6;
PBox[6] = this.pictureBox7;
PBox[7] = this.pictureBox8;
PBox[8] = this.pictureBox9;
for (int i = 0; i < 9; i++)
{
PBox[i].Click += new System.EventHandler(PBoxes_Click);
}
}
public void PBoxes_Click(object sender, EventArgs e)
{
PictureBox myPictureBox = sender as PictureBox;
//if(Pbox[1].click){
//^^ Looking for something like this
}
My question is how can I tell which one of my pictureboxes has been clicked as i am unable to access any of them. I would just like to be able to tell which has been clicked inside the method instead of creating many.
pictureBox1_Click(object sender, EventArgs e)
Like Events
There a multiple ways to solve the issue.
You could cast sender to the correct type (here PictureBox):
public void TicTac_Load(object sender, EventArgs e)
{
PictureBox[] PBox = new PictureBox[9];
PBox[0] = this.pictureBox1;
PBox[1] = this.pictureBox2;
PBox[2] = this.pictureBox3;
PBox[3] = this.pictureBox4;
PBox[4] = this.pictureBox5;
PBox[5] = this.pictureBox6;
PBox[6] = this.pictureBox7;
PBox[7] = this.pictureBox8;
PBox[8] = this.pictureBox9;
for (int i = 0; i < 9; i++)
{
PBox[i].Click += new System.EventHandler(PBoxes_Click);
}
}
public void PBoxes_Click(object sender, EventArgs e)
{
PictureBox myPictureBox = sender as PictureBox;
}
Alternatively (less-recommended), you could move PBox to a class-level array:
PictureBox[] PBox = new PictureBox[9];
public void TicTac_Load(object sender, EventArgs e)
{
PBox[0] = this.pictureBox1;
PBox[1] = this.pictureBox2;
PBox[2] = this.pictureBox3;
PBox[3] = this.pictureBox4;
PBox[4] = this.pictureBox5;
PBox[5] = this.pictureBox6;
PBox[6] = this.pictureBox7;
PBox[7] = this.pictureBox8;
PBox[8] = this.pictureBox9;
for (int i = 0; i < 9; i++)
{
PBox[i].Click += new System.EventHandler(PBoxes_Click);
}
}
public void PBoxes_Click(object sender, EventArgs e)
{
PictureBox myPictureBox = PBox[PBox.indexOf(sender)];
}

C# Searchable, Positionable PictureBox

I've been searching about this for a while and haven't found what I'm looking for.
I want to be able to have an image in a picturebox that can be positioned to a point by means of a "search box". Basically, mapping locations in pixels to certain phrases or letters that then shift the position on the picturebox.
I tried to set the location using points, however this does not change the picture at all; the location after calculating the code below stubbornly stays at (3,3).
The picture also is large (~3500 x ~3000) and needs scrolls bars to fully view it.
Here's my code
public Form1()
{
InitializeComponent();
flowLayoutPanel1.AutoScroll = true;
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
flowLayoutPanel1.Controls.Add(pictureBox1);
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "m")
{
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = Image.FromFile(#"C:\User\Desktop\map.jpg");
pictureBox1.Location = new Point(700, 200);
// ^ The location does not change and stays at (3,3)
// The picturebox is not set as locked
}
Do I need to do something different? Or is the issue with my picture for not allowing me to change the location?
EDIT I found the Solution thanks to the help below. I had to use a panel and place the picturebox within. Below is the code I used.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
panel1.AutoScroll = true;
panel1.Controls.Add(pictureBox1);
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = Image.FromFile(#"C:\Desktop\image.jpg");
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Visible = true;
label1.Visible = true;
int Hvalue = panel1.HorizontalScroll.Value;
label1.Text = Hvalue.ToString();
label2.Visible = true;
int Vvalue = panel1.VerticalScroll.Value;
label2.Text = Vvalue.ToString();
if (textBox1.Text == "m")
{
// these are just values that I put in
panel1.HorizontalScroll.Value = 616;
panel1.VerticalScroll.Value = 90;
}
}

dynamically changing picture box

i dynamically create several picture box, and EventHandler. when user click on pictureBox, the program should delete tрis item. (the item that the user selected)
i try do
for (int i = 1; i <= sunduki; i++)
{
PictureBox PBObj = new PictureBox();
PBObj.Location = new System.Drawing.Point(i * 100, 101);
PBObj.Name = "pictureBox" + i.ToString();
PBObj.Size = new System.Drawing.Size(108, 80);
PBObj.TabIndex = i;
PBObj.BackgroundImage = Image.FromFile(#"syndyk1.jpg");
PBObj.BackgroundImageLayout = ImageLayout.Zoom;
PBObj.Click += new System.EventHandler(pb_Click);
PB.Add(PBObj);
Controls.Add(PB[PB.Count - 1]);}
and in pb_click
private void pb_Click(object sender, EventArgs e)
{ PB[this].Visible = false; }
but i have an error. (PB is the list with pictureBox)
The sender argument will be the object that has been clicked, in this case it is the PictureBox object.
private void pb_Click(object sender, EventArgs e)
{
var pb = sender as PictureBox;
if(pb != null)
{
pb.Visible = false;
}
}
Note: This doesn't delete the picture box, but makes it not visible. Controls deletion is handled by the disposal of the form.

Get the index of array of picturebox clicked

I am creating some picturebox dynamically and click event for picturebox as follows
Image myImage = Image.FromFile("image/Untitled6.png");
PictureBox[] txtTeamNames = new PictureBox[5];
for (int i = 0; i < txtTeamNames.Length; i++)
{
var txt = new PictureBox();
txtTeamNames[i] = txt;
txtTeamNames[i].Image = myImage;
txtTeamNames[i].Height = 53;
txtTeamNames[i].Width = 48;
this.panel1.Controls.Add(txtTeamNames[i]);
txtTeamNames[i].Visible = true;
txtTeamNames[i].Click += new EventHandler(this.clcikeventhandle);
}
When someone clicks on any picture box, how do I find its array index and name?
void clickEventHandler(object sender, EventArgs e)
{
//???
}
You can access the PictureBox via the sender argument. So try this:
PictureBox[] txtTeamNames;
void YourMethod()
{
Image myImage = Image.FromFile("image/Untitled6.png");
txtTeamNames = new PictureBox[5];
//The same as your code
}
void clcikeventhandle(object sender, EventArgs e)
{
int index = txtTeamNames.IndexOf(sender As PictureBox);
}
EDIT: Approach #2
But if you are not happy with declaring that array in the class scope you can try this approach:
//Same as your code
for (int i = 0; i < txtTeamNames.Length; i++)
{
//Save as your code
txtTeamNames[i].Tag = i; // ADD THIS LINE
}
Then:
void clcikeventhandle(object sender, EventArgs e)
{
int index = int.Parse((sender as PictureBox).Tag.ToString());
}
Another suggestion - create a custom class, which inherits from PictureBox. It will have an extra Index property. And you can set it between these two lines:
txtTeamNames[i].Visible = true;
//assign the index here
txtTeamNames[i].Click += new EventHandler(this.clcikeventhandle);
like so:
txtTeamNames[i].Index = i;
Then in the handler:
void clickEventHandle(object sender, EventArgs e)
{
PictureBox pbox = sender As PictureBox;
int index = pbox.Index();
string name = pbox.Name();
}
You keep the same scope of variables, which may be useful if you are concerned about it. If you are okay with upgrading scope of txtTeamNames to class level, see another answer by Hossein Narimani Rad.
namespace your_name_project
{
public partial class Form_Begin : Form
{
PictureBox[] pictureBoxs = new PictureBox[6];
public Form_Begin()
{
InitializeComponent();
pictureBoxs[0] = pictureBox1; pictureBoxs[1] = pictureBox2; pictureBoxs[2] = pictureBox3;
pictureBoxs[3] = pictureBox4; pictureBoxs[4] = pictureBox5; pictureBoxs[5] = pictureBox6;
}
//continue
List<PictureBox> pictureBoxes = new List<PictureBox>();
private void buttonX1_Click(object sender, EventArgs e)
{
for (int i = 0; i <3; i++)
{
pictureBoxs[i].Image =your_name_project.Properties.Resources.image_1;// load image1 and Image_2from resource in property of picturebox
}
for (int i = 3; i < 6; i++)
{
pictureBoxs[i].Image = your_name_project.Properties.Resources.Image_2;
}
}
}
}
I've tried the 1st approach cited above, but it did not work for me. I needed to change the syntax in order to work. I am unsure why, but my way for approach 1 to work would be:
PictureBox[] txtTeamNames;
void YourMethod()
{
Image myImage = Image.FromFile("image/Untitled6.png");
txtTeamNames = new PictureBox[5];
//The same as your code
}
void clcikeventhandle(object sender, EventArgs e)
{
int index = Array.IndexOf(txtTeamNames, sender); //DIFFERENT HERE
}
If anyone has an idea...

How can i remove from a pictureBox the background image only and leave on the pixels i drawed?

This is the Play button code:
private void btnPlay_Click(object sender, EventArgs e)
{
_files = new List<FileInfo>();
_indx = 0;
DirectoryInfo dir = new DirectoryInfo(filesForanimation);
if (_files == null)
_files = new List<FileInfo>();
fi1 = dir.GetFiles("*.bmp");
_files.AddRange(fi1);
_files = _files.OrderBy(f => f.LastWriteTime).ToList();
button14.ForeColor = Color.Red;
button13.ForeColor = Color.Black;
button12.ForeColor = Color.Black;
timer3.Start();
button13.Enabled = true;
button13.Text = "Pause";
button12.Enabled = true;
trackBar1.Maximum = fi1.Length;
trackBar1.Minimum = 0;
}
Then the timer tick event:
private void timer3_Tick(object sender, EventArgs e)
{
try
{
Image iOLd = this.pictureBox1.Image;
trackBar1.Value = _indx;
label23.Text = _files[_indx].Name;
if (checkBox1.Checked)
{
Image img = Image.FromFile(_files[_indx].FullName);
this.pictureBox1.Image = img;
this.pictureBox1.Image = null;
pictureBox1.Refresh();
}
else
{
Image img = Image.FromFile(_files[_indx].FullName);
this.pictureBox1.Image = img;
}
if (iOLd != null)
// iOLd.Dispose();
_indx++;
if (_indx >= _files.Count)
{
_indx = 0;
trackBar1.Value = 0;
}
timer3.Interval = Convert.ToInt32(numericUpDown1.Value);
}
catch
{
}
}
And the checkBox check event:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
Graphics g = Graphics.FromImage(pictureBox1.Image);
g.Clear(SystemColors.Control);
pictureBox1.Invalidate();
}
else
{
pictureBox1.Load(fi[trackBar1.Value].FullName);
pictureBox1.Invalidate();
}
}
The problem is in the timer tick. First time i tried inside the if (checkBox1.Checked) i did only pictureBox1.Refresh(); but then when hitting play button its showing big red X with white background. So i marked // the line: iOLd.Dispose(); so now i see the drawings the pixels only but they never change i guess for some reason it dosent load the new image from the hard disk as it suppose to do so its keep moving over and over the same image.
So i tried in the if (checkBox1.Checked)
to do as it is now:
Image img = Image.FromFile(_files[_indx].FullName);
this.pictureBox1.Image = img;
this.pictureBox1.Image = null;
pictureBox1.Refresh();
But in this case the trackBar and the timer moving once to image number 2 and stop there without doing anything.
And this happennig only when the checkBox is checked if its not checked and in the pictureBox there are the pixels and the background image its working fine.
** I modified cleared and made the question shorter **
You should not draw onto a graphics object from a non-persisted method such as a check change event.
You should handle the Paint event of the PictureBox so that your graphics are redrawn each time the PictureBox needs to refresh (such as when changing the background image). As it stands you will most likely lose your graphics if you move the window around enough too.
For example:
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
// draw your pixels here
}
NOTE: Picture boxes have there uses and there problems, if you want to do custom drawing I would recommend just drawing onto a standard panel instead.

Categories