Search code examples
c#winformseventspicturebox

How to get specific PictureBox from Button Click event?


Here is my code:

private void button1_Click(object sender, EventArgs e)
{
    Button btn = sender as Button;
    PictureBox pic = sender as PictureBox;

    if (btn != null)
    {
        btn.Visible = false;
    }
    i++;
    if(i == 2)
    {
        if (compare(image1, image2))
        {
            pic.Visible = false;
        }
        else
        {
            btn.Visible = true;
        }
    }
    else
    {
        //nothing yet
    }
    MessageBox.Show(i.ToString());
}

Code works like, if 2 buttons clicked, it should check if 2 picture boxes behind clicked buttons have the same image, if they have just hide that picture boxes, if not set button visibility to true.. Now, the problem is that I do not know how should I write code to work as I want..

private void button1_Click(object sender, EventArgs e)

Works like an event for 20 buttons.


Solution

  • I am going to ahead and take a guess here. From what I can tell is that on the Form, there are twenty (20) PictureBoxes and twenty (20) Buttons. In addition there are a total of ten (10) “different” images (pictures). Each of the ten images is used exactly twice in two of the twenty (20) PictureBoxes. These images are randomly placed into each picture box.

    The goal is for the user to select two “matching” images by clicking on one button to reveal a picture, then click another button to reveal a second image. If the images are the same, then remove (make invisible) the buttons associated with those pictures and then leave the pictures displayed. Then the user starts again to pick two more matching pictures.

    If the user selects two (2) NON-matching pictures, then we want to display a dialog box indicating that the pictures do not match, then, make those pictures invisible and set the buttons back to visible and allow the user to try again. A basic find the two matching pictures game.

    If this is the case, then, the code below is one simplistic approach. The approach used depends on creating two (2) global variables… 1) a Button called curButton… this will be the FIRST button the user clicks to reveal the FIRST selected image. And 2) a PictureBox called curPictureBox that will hold the PictureBox associated with that first clicked button.

    Initially BOTH global variables will be null which will indicate that the user has NOT selected the first picture. Once the user selects the first picture by pressing one of the twenty buttons, the code will set these two global variables to point to the selected Button and it's associated PictureBox. … Then…

    When the user clicks on a different button, we will check to see if the curButton is null… if curButton is NOT null, then, this would mean that the user has clicked on the second button. At this point the code would reveal the picture of the second clicked button to the user, then check to see if the pictures match. If the pictures match, then, the code will display a dialog stating such and after the user clicks the OK in the dialog, those two buttons will no longer be available and the pictures will remain displayed since the user found the match.

    If the pictures do NOT match, then hide both pictures and make each button visible. And finally in both cases where a match is found or not found, the code sets curButton and curPictureBox back to null to start the whole (pick two pictures) process over.

    As you have noted, one issue you are having is identifying “which” PictureBox belongs to “which” Button. In other words, we can easily identify the Button that was clicked in the buttons click event, however, this does not tell us “which” PictureBox is associated with that Button. This can be done in a myriad of ways. A Class or even a custom Control with a picture box and button are certainly reasonable and good options. This would “tie” the button and picture box together and would make identifying with picture box belongs to the button a moot point.

    However, in this simple case, I have simply created a method that takes a Button and returns the PictureBox associated to the passed in Button… we will use the buttons Name property to identify which picture box is associated to the given button. This brute force approach may look something like…

    private PictureBox GetPBFromButton(Button button) {
      switch (button.Name) {
        case "button1":
          return pictureBox1;
        case "button2":
          return pictureBox2;
        case "button3":
          return pictureBox3;
        case "button4":
          return pictureBox4;
        case "button5":
          return pictureBox5;
        case "button6":
          return pictureBox6;
        case "button7":
          return pictureBox7;
        case "button8":
          return pictureBox8;
        case "button9":
          return pictureBox9;
        case "button10":
          return pictureBox10;
        case "button11":
          return pictureBox11;
        case "button12":
          return pictureBox12;
        case "button13":
          return pictureBox13;
        case "button14":
          return pictureBox14;
        case "button15":
          return pictureBox15;
        case "button16":
          return pictureBox16;
        case "button17":
          return pictureBox17;
        case "button18":
          return pictureBox18;
        case "button19":
          return pictureBox19;
        default:
          return pictureBox20;
      }
    }
    

    This will be used in the buttons click event. And in reference to the button click event, it should be noted that making twenty (20) events (one for each button) will complicate things and create a bunch of duplicate code. In other words, the “action” performed when a button is click will be the same for ALL buttons and the only difference will be which button is clicked and which picture box is associated with that button. Therefore we will wire up ALL the buttons to this single event.

    Walking through the code will go something like… When a button is clicked, the code will grab the clicked Button object and set it to a variable named clickedButton. Then using our method above, we will get the PictureBox associated with that button.

    Next, the code checks to see if this is the first button clicked or the second button clicked. If curButton is null, then, this is the first button clicked. If curButton is NOT null, then, this is the second button clicked.

    When the first button is clicked the code simply sets the two global variables to the selected controls and displays the picture and hides the pictures button. Then the code waits until the user clicks the second button.

    When the second button is clicked, a check is made to see if the two images are the same image. If the images are the same images, then, the code simply hides both those buttons and leaves the pictures visible since the user found a match. Finally the code sets the two global variables to null to allow the user to start selecting two more buttons.

    A special note on the Image comparison on the following line of code…

    if (curPictureBox.Image != pb.Image) { … 
    

    This equality will ONLY work if BOTH picture boxes contain the SAME Image object. In this example, I used the SAME Image object for BOTH picture boxes. If TWO different Image objects are used such that the Image objects are different yet contain the SAME picture, then the code above will fail since the memory references will obviously always be different. You may need to adjust this, depending on how the images are added to the picture boxes.

    enter image description here

    enter image description here

    Button curButton = null;
    PictureBox curPictureBox = null;
    
    private void All_Buttons_Click(object sender, EventArgs e) {
      Button clickedButton = (Button)sender;
      PictureBox pb = GetPBFromButton(clickedButton);
      if (curButton == null) {
        // first button clicked
        curButton = clickedButton;
        curPictureBox = pb;
        clickedButton.Visible = false;
        curPictureBox.Visible = true;
      }
      else {
        // second button clicked
        clickedButton.Visible = false;
        pb.Visible = true;
        if (curPictureBox.Image != pb.Image) {  // <- your compare method?
          MessageBox.Show("No match - click ok to try again!");
          clickedButton.Visible = true;
          pb.Visible = false;
          curPictureBox.Visible = false;
          curButton.Visible = true;
        }
        else {
          MessageBox.Show("Match Found - click ok to continue!");
        }
        curButton = null;
        curPictureBox = null;
      }
    }