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...
Related
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)];
}
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);
}
i was trying to make this code:
public void _open_Click_1(object sender, EventArgs e)
{
_playList.Items.Clear();
_openFile.Multiselect = true;
_openFile.Filter = "Mp3 Files|*.mp3|Avi Files|*.avi|Mp4 Files|*.mp4";
_openFile.ShowDialog();
doc = _openFile.SafeFileNames;
path = _openFile.FileNames;
for (int i = 0; i < doc.Length; i++)
{
_playList.Items.Add(doc[i]);
}
}
from a class
so i created a class called mplayer
and then an instance of the form
and put all that code in there
what suppose to happen is when i click a button
file dialog opens
and all selected song names would go into a listbox
for some reason it doesn't open and no compilation nor exception errors pops
please advise
As I can see the event handler is correctly assigned. Btw try this code, it is working in my project:
public Form1()
{
InitializeComponent();
_open.Click += new EventHandler(_open_Click_1);
}
private void _open_Click_1(object sender, EventArgs e)
{
_openFile = new OpenFileDialog();
_playList.Items.Clear();
_openFile.Multiselect = true;
_openFile.Filter = "Mp3 Files|*.mp3|Avi Files|*.avi|Mp4 Files|*.mp4";
_openFile.ShowDialog();
var doc = _openFile.SafeFileNames;
var path = _openFile.FileNames;
for (int i = 0; i < doc.Length; i++)
{
_playList.Items.Add(doc[i]);
}
}
Note: I was using local variables for the selected file names and path.
maybe i wasn't explaining myself very well. im trying to call a class which does that. like this
public static class mplayer
{
public static void openMusic()
{
PhoenixDownloader.searchForm frm = new searchForm();
frm._playlist.items.clear();
frm._openfile.multiselect = true;
frm._openfile.filter = "mp3 files|*.mp3|avi files|*.avi|mp4 files|*.mp4";
frm._openfile.showdialog();
frm.doc = frm._openfile.safefilenames;
frm.path = frm._openfile.filenames;
for (int i = 0; i < frm.doc.length; i++)
{
frm._playlist.items.add(frm.doc[i]);
}
}
}
}
and on the event part:
public void _open_Click_1(object sender, EventArgs e)
{
mplayer();
}
and it it doesn't happen
I have a small program that generates four dynamic buttons on load in a flowLayoutPanel1 and a static save button.
My aim is to save the dynamic button colors so that when the form is reloaded or opened again the colors of the dynamic buttons are loaded back up in the same state as saved.
Below I will include my code which has been commented to demonstrate what I have attempted.
I am using an xml file to save the button state and included a class that holds the state. However the method I am using works fine if a create my buttons to save statically. (I have only tried it with one static button)
Interface:
class that holds state:
public class MyFormState
{
public string ButtonBackColor { get; set; }
}
Form code:
public partial class Form1 : Form
{
//Form Member
MyFormState state = new MyFormState();
Button btn;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//loading xml file if it exists
if (File.Exists("config.xml"))
{
loadConfig();
}
//Genrating dynamic buttons
// flowLayoutPanel1.Controls.Clear();
for (int i = 0; i <= 3; ++i)
{
btn = new Button();
btn.Text = " Equation " + i;
flowLayoutPanel1.Controls.Add(btn);
//click event of buttons
btn.Click += new EventHandler(btn_Click);
}
btn.BackColor = System.Drawing.ColorTranslator.FromHtml(state.ButtonBackColor);
}
//method to load file
private void loadConfig()
{
XmlSerializer ser = new XmlSerializer(typeof(MyFormState));
using (FileStream fs = File.OpenRead("config.xml"))
{
state = (MyFormState)ser.Deserialize(fs);
}
}
//saving the xml file and the button colors
private void writeConfig()
{
using (StreamWriter sw = new StreamWriter("config.xml"))
{
state.ButtonBackColor = System.Drawing.ColorTranslator.ToHtml(btn.BackColor);
XmlSerializer ser = new XmlSerializer(typeof(MyFormState));
ser.Serialize(sw, state);
}
}
int count = 0;
//backcolor change
void btn_Click(object sender, EventArgs e)
{
Button button = sender as Button;
if (count == 0)
{
button.BackColor = Color.Red;
count++;
}
else if (count == 1)
{
button.BackColor = Color.Blue;
count--;
}
}
//save file
private void btnSave_Click(object sender, EventArgs e)
{
writeConfig();
}
}
Any suggestions on what i should change so that it works for me? Thanks
Your code works fine but only for the last button. You have 4 buttons but only have one MyFormState object. When creating the buttons you always use the same private field btn. So you need arrays of 4 MyFormState objects and 4 buttons.
MyFormState[] states = new MyFormState[4];
Button[] buttons = new Button[4];
private void Form1_Load(object sender, EventArgs e)
{
if (File.Exists("config.xml"))
{
loadConfig();
}
for (int i = 0; i < 4; ++i)
{
buttons[i] = new Button();
buttons[i].Text = " Equation " + i;
flowLayoutPanel1.Controls.Add(buttons[i]);
buttons[i].Click += new EventHandler(btn_Click);
if (states[i] != null)
{
buttons[i].BackColor = ColorTranslator.FromHtml(states[i].ButtonBackColor);
}
}
}
private void loadConfig()
{
XmlSerializer ser = new XmlSerializer(typeof(MyFormState[]));
using (FileStream fs = File.OpenRead("config.xml"))
{
states = (MyFormState[])ser.Deserialize(fs);
}
}
private void writeConfig()
{
for (int i = 0; i < 4; i++)
{
if (states[i] == null)
{
states[i] = new MyFormState();
}
states[i].ButtonBackColor = ColorTranslator.ToHtml(buttons[i].BackColor);
}
using (StreamWriter sw = new StreamWriter("config.xml"))
{
XmlSerializer ser = new XmlSerializer(typeof(MyFormState[]));
ser.Serialize(sw, states);
}
}
I would like to automatically create a PictureBox. How to change this in the code:
private void button1_Click(object sender, EventArgs e)
{
PictureBox[] box = new PictureBox[textBox1.Text.Length];
for(int j=0;j<textBox1.Text.Length;j++)
box[0] = pictureBox1;
box[1] = pictureBox2;
box[2] = pictureBox3;
for (int i = 0; i < textBox1.Text.Length; ++i)
box[i].Image = Image.FromFile(string.Format(#"c:\obrazki\{0}.jpg",textBox1.Text[i]));
}
You should probably use a FlowLayoutPanel control to hold your PictureBox controls. Then the code would look something like this:
void button1_Click(object sender, EventArgs e) {
while (flowLayoutPanel1.Controls.Count > 0) {
flowLayoutPanel1.Controls[0].Dispose();
}
for (int i = 0; i < textBox1.Text.Length; ++i) {
PictureBox pb = new PictureBox();
pb.Image = Image.FromFile(string.Format(#"c:\obrazki\{0}.jpg",textBox1.Text[i]));
flowLayoutPanel1.Controls.Add(pb);
}
}