How to get the index - c#

For a school project, I have to make a table reservation system,
I made the following (just a small part).
PictureBox[] pb = new PictureBox[70] { pictureBox1, pictureBox2, pictureBox3,etc.. };
foreach (PictureBox p in pb)
{
p.BorderStyle = BorderStyle.Fixed3D;
p.BackColor = Color.White;
p.MouseEnter += new EventHandler(mouseOn);
p.MouseClick += new MouseEventHandler(mouseClick);
}
private void mouseOn(object sender, EventArgs e)
{
((PictureBox)sender).BackColor = Color.Green;
}
private void mouseClick(object sender, EventArgs e)
{
reservationForm rf = new reservationForm();
rf.ShowDialog();
}
I chose for pictureboxes to represent the tables, the default BackColor is white, and when the mouse enters the BackColor turns green.
When you click on 1 of those PictureBoxes my reservationForm will open, this is where you can further fill in the details to book the table.
but the part where I get stuck now is that I don't know on my reservation form which PictureBox I clicked, so I need to get something like the index of the PictureBox array.
How do I fix this?

You know how to do it! :)
You're already doing it correctly on the mouseOn event handler. Just do the same cast of the sender parameter.
private void mouseClick(object sender, EventArgs e)
{
PictureBox clickedBox = (PictureBox)sender;
reservationForm rf = new reservationForm();
rf.ShowDialog();
}
If you need the index, you can use Array.IndexOf, assuming your pb array is a class level variable and not a method local.
int index = Array.IndexOf(pb, clickedBox);

Check sender
private void mouseClick(object sender, EventArgs e)
{
PicterBox pb = (PicterBox)sender;
...
}

In your "MouseOn" you already use (PictureBox)sender to get a reference to the picturebox.
Then you can walk through the array to compare the picturebox at a specific index to the clicked one. When you have a match, you found the index.
var clicked = (PictureBox)sender;
int index = 0;
while (index < pb.Length && pb[index] != clicked) index = index+1;
// now index is either 70 (if not found) or the position you want (0..69)

Maybe you can set in for cycle a name at each picturebox equals at the corrispondent index. So in the listener u can use
PicterBox pb = (PicterBox)sender;
and get the name that is the index.

You have many options. I will suggest some of them:
Create a public class variable or property and store the current selected Picturebox on the click event, so you can access it from the form;
Pass in the Picturebox for the constructor of the form (creating a constructor that accepts this info and stores it in an internal variable).

Related

C# ClickEvent - Override previous handler

I have a method which run on a click of a button.
The methods goes to a database and return all products ids(list) wihich match
a specific keyword.
It then uses that id to get the corresponding image from the database
and adds it to a picturebox.
The problem I have is with adding the click evethandler to each picturebox. If I click the search button a second time there is now two eventhndler registered to that picturebox and so on. So when I click on a picurebox sfter pressing the search button twice i will het two messagebox.
Is there a way to drop the previous and only keep the latest eventhandler?
private void btnSearch_Click(object sender, EventArgs e)
{
ClearPicBoxs();
if((!txtBoxSearch.Text.Equals("Search...") || !txtBoxSearch.Text.Equals("")) && isLoggedIn)
{
//Get Product ids from database which have supplied keyword
DAOKeyword.SelectKeywords(txtBoxSearch.Text, productIdsList);
int cnt = 0;
foreach (int productId in productIdsList)
{
ImageDAOImpl DAOIamge = new ImageDAOImpl();
picPrd = pictureBoxList[cnt];
picPrd.Text = productId.ToString();
picPrd.Click += new System.EventHandler((sender1, e1) => picPrd_Click(sender, e, productId));
picPrd.Image = ByteArrayToImagebyMemoryStream(DAOIamge.SelectImage(productId));
picPrd.SizeMode = PictureBoxSizeMode.StretchImage;
picPrd.Refresh();
cnt++;
}
lblLatest_Search.Text = "''" + txtBoxSearch.Text + "''";
productIdsList.Clear();
}
else
{
//Select Latest Posted Products
}
}
private void picPrd_Click(object sender, EventArgs e, int productId)
{
//Use productId to get info about product
MessageBox.Show(productId.ToString());
}
I am not sure where is the list pictureBoxList is populated, and why you need to assign its items to your controls as long as you set control properties manually.
If you re-instantiate the control each time before assigning the event handler, it should fire it only once
My suggestion is to replace the below line
picPrd = pictureBoxList[cnt];
With the below line
picPrd = new PictureBox();

Right click event, I need to get actual component that is right clicked as sender instead of ContextMenuItem

I am applying right click option on a PictureBox to delete that picture from a virtual Folder
tried following code:
main()
{
//Some where in main()
PictureBox pb = new PictureBox();
pb.ContextMenu = contextMenu_pictureBoxRightClick;
}
private void menuItem1_Click(object sender, EventArgs e)
{
//Here sender is actual the menuItem which is clicked after right Clicking the picture
PictureBox pb = (PictureBox)sender;
// Doing somthing to PictureBox!!!
}
but receive error casting because sender is actual ContextMenuItem
You can get the actual component (PictureBox in this case) that was right-clicked from ContextMenuItem this way :
var menuItem = (MenuItem)sender;
var ctxMenu = (ContextMenu)menuItem.Parent;
var actualComponent = (PictureBox)ctxMenu.SourceControl;
//or in short
var actualComponent = (PictureBox)((ContextMenu)((MenuItem)o).Parent).SourceControl;
This code is failing because sender represents the object on which the event occured. In this case it is the menu item and not the PictureBox
It sounds like you want to access a PictureBox value when a specific menu item is clicked. If that is the case then the best route is to make the PictureBox value a field and access it directly from the click handler
PictureBox pb;
main() {
...
pb = new PictureBox();
pb.ContextMenu = contextMenu_pictureBoxRightClick;
}
private void menuItem1_Click(object sender, EventArgs e) {
// pb can be used directly here
}

Trying to make a picturebox accept a int as number

I am trying to do the following action with pictureboxes:
Search for a picturebox that has a special image, my method for this returns a number of the box that has this image.
Example:
if (picturebox1.Tag == "special") {
return 1; //returns value 1 as in picturebox1 contains it.
}
Now when I click on pictureBox2 I want it to switch with the picturebox that contains the special picture (I have a total of 10 pictureboxes with pictures, only one box contains a special one)
Click event on picturebox2:
private void pictureBox2_Click(object sender, EventArgs e)
{
performSwitch(2); //2 meaning picturebox "2"
}
Method it calls:
public void performSwitch(int pictureBoxWaarde)
{
switch (pictureBoxWaarde)
{
case 2:
pictureBox10.Image = pictureBox2.Image; //else picture overwrites
pictureBox2.Image = pictureBox1.Image;
pictureBox1.Image = pictureBox10.Image;
break;
}
}
This code works however I dont want to make TONS of if-else statements for every combination there is.. So to make it 'smart' I will need something like this:
public void performSwitch(int pictureBoxWaarde)
{
switch (pictureBoxWaarde)
{
pictureBox10.Image = pictureBox2.Image; //else picture overwrites
pictureBox2.Image = pictureBox"+findBlackBox+".Image;
pictureBox"+findBlackBox()+".Image = pictureBox10.Image;
break;
}
}
If this would work it would get the special box number and work without the need of lots of if-else. How would I do this?
I'm not sure whether I fully understand what you're trying to achieve, but you can always find a control by its name.
Let's say that you have a variable string m_specialPictureBoxName; that always contains the name of the current special picture box, you could do the following:
public void performSwitch(int pictureBoxWaarde)
{
// Get current special picture box
PictureBox currentSpecial = this.Controls.Find(m_specialPictureBoxName, true) as PictureBox;
// Get new special picture box
m_currentPictureBoxName = String.Format("pictureBox{0}", pictureBoxWaarde);
PictureBox clicked = this.Control.Find(m_currentPictureBoxName, true) as PictureBox;
// Swap images
Image temp = currentSpecial.Image;
currentSpecial.Image = clicked.Image;
clicked.Image = temp;
}
Also I'm swapping the image without using the temporary pictureBox10 assignment - I'm not sure whether you want pictureBox10 to get the image. If you do, you can replace it with your previous code instead of the Image temp = ...line.
Assign all the PictureBox event handlers to a single method.
Write the method like this
private void ApictureBox_Click(object sender, EventArgs e)
{
var clickedPicture = sender as PictureBox;
// iterate through all picture controls of the current form
for (var pic in this.Controls.OfType<PictureBox>())
if (pic.Tag=="special")
{
var temp = clickedPicture.Image;
clickedPicture.Image = pic.Image;
pic.Image = temp;
}
}
For the first step, you can either do it manually, or use a similar loop to assign the event handlers in the form constructor.

Check state of every picturebox together on submit

Here is my question:
Im making a booking cinema system in c#, windows form
Let's say i have 5 columns of 5 rows of pictureboxes that on form load get their value, avaliable or not from the database.
The user then click on the seat he wants (and the image of the pictuebox change) and press a submit button.
How i can check the image of every picturebox (to determine if he want this seat or not) together?
I can do something like this
if (picturebox11.image=="seatchecked"){seats[]+=11;}
if (picturebox12...
But im wondering if there is another faster way to do it. (the position of the pictureboxes is fixed if that helps)
I have done this so far:
private void button1_Click(object sender, EventArgs e)
{
List<PictureBox> pb = new List<PictureBox>();
pb.Add(seat11);
pb.Add(seat12);
pb.Add(seat13);
pb.Add(seat14);
pb.Add(seat15);
pb.Add(seat21);
pb.Add(seat22);
pb.Add(seat23);
pb.Add(seat24);
pb.Add(seat25);
pb.Add(seat31);
pb.Add(seat32);
pb.Add(seat33);
pb.Add(seat34);
pb.Add(seat35);
for (int i = 0; i < 20; i++) {
pb[i].Click += pictureBox_Click;
}
}
void pictureBox_Click(object sender, EventArgs e)
{
this.pictureBox.Image = ArgyroCinema.Properties.Resources.seatred;
}
Store each PictureBox in a list and iterate through them. Also, when the user selects/deselects a seat, change the Tag property of the PictureBox as, at the moment, you're trying to compare a string to an Image (picturebox11.Image returns an Image object).
List<PictureBox> pb = new List<PictureBox>();
pb.Add(pictureBox1);
pb.Add(pictureBox2);
//etc..
Alternatively, you can use the methods suggested here to get all PictureBox objects in your form to save you having to type it out above.
Then just iterate through them and read their Tag property. In this case I've used true to represent that they want the seat but Tag is an object type, so you can use whatever type you like.
foreach(PictureBox p in allPictureBoxes)
{
if((bool)p.Tag == true)
{
//seat wanted
}
else
{
//seat not wanted
}
}
Update from comments
void pictureBox_Click(object sender, EventArgs e)
{
PictureBox pb = sender as PictureBox;
if(pb != null)
pb.Image = ArgyroCinema.Properties.Resources.seatred;
}

Problem In event generation of Dynamically Generated Picturebox

i have generated picturebox dynamically... now i have to displaying Different images on that picture boxes after that when i click the particular picture box it should be displayed in the next form Picture box.... how do i know the particular picturebox got clicked.... and How can I do it... reply me.. Thanks In Advance..
and my coding is
for(int i=0;i<Num_Picbox;i++)
{
shapes[i].Location = new Point(Left,Top);
Left += 200;
Top += i + 0;
shapes[i].Size = new Size(150, 150);
shapes[i].BackColor = Color.Black;
shapes[i].Visible = true;
shapes[i].BorderStyle = BorderStyle.FixedSingle;
this.Controls.Add(shapes[i]);
shapes[i].Click += new EventHandler(PictureBox_Click);
}
private void PictureBox_Click(object sender, EventArgs e)
{
int imageid = 1;
ClsProperty.ImageId = imageid;
fd2 = new frmImageDisplay(imageid, ClsProperty.ipaddress);
fd2.Show();
}
The "sender" in the event handler will be the picture box that got clicked:
private void PictureBox_Click(object sender, EventArgs e) {
PictureBox senderAsPictureBox = sender as PictureBox;
//this is the picture box that got clicked
int imageid = 1;
ClsProperty.ImageId = imageid;
fd2 = new frmImageDisplay(imageid, ClsProperty.ipaddress);
fd2.Show();
}
It would be helpful if you show your code, but anyways,
if you are dynamically creating a picture box, you can add a code like .Click += your method name.
This is more help about dynamically adding an event to the control when adding them
Hope it helps
Ok, I think it's easy, the first argument of event is always object sender,
cast it to the picture box object and read the ID property, and you can move forward with your problem!

Categories

Resources