如何从 Button Click 事件中获取特定的 PictureBox?

How to get specific PictureBox from Button Click event?

这是我的代码:

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());
}

代码的工作原理是,如果单击了 2 个按钮,它应该检查单击的按钮后面的 2 个图片框是否具有相同的图像,如果它们只是隐藏了那个图片框,如果没有将按钮可见性设置为 true..现在,问题是我不知道应该如何编写代码才能按我的意愿工作..

private void button1_Click(object sender, EventArgs e)

就像 20 个按钮的事件。

我先来猜一猜。据我所知,在 Form 上,有二十 (20) 个 PictureBoxes 和二十 (20) 个 Buttons。此外,共有十 (10) 个“不同”图像(图片)。十张图像中的每一张在二十 (20) 张 PictureBoxes 中的两张中恰好使用了两次。这些图片随机放入每个图片框。

目标是让用户 select 两张“匹配”的图像,方法是单击一个按钮显示一张图片,然后单击另一个按钮显示第二张图像。如果图像相同,则删除(使其不可见)与这些图片关联的按钮,然后让图片保持显示状态。然后用户再次开始选择另外两张匹配的图片。

如果用户select有两 (2) 张不匹配的图片,那么我们要显示一个对话框,指示图片不匹配,然后,使这些图片不可见并将按钮设置回来可见并允许用户重试。一个基本的找到两张匹配图片的游戏。

如果是这种情况,那么,下面的代码是一种简单化的方法。使用的方法取决于创建两 (2) 个全局变量……1) 一个名为 curButtonButton……这将是用户单击以显示第一个 selected 图像的第一个按钮。 2) 一个名为 curPictureBoxPictureBox 将保存与第一次单击的按钮关联的 PictureBox

最初两个全局变量都将是 null,这将表明用户还没有 select 编辑第一张图片。一旦用户 select 通过按下 20 个按钮中的一个按钮获得了第一张图片,代码就会将这两个全局变量设置为指向 selected Button 并且它关联 PictureBox. ……然后……

当用户点击不同的按钮时,我们将检查 curButton 是否为 null…如果 curButton 不是 null,那么,这意味着用户点击了第二个按钮。此时代码会向用户显示第二个单击按钮的图片,然后检查图片是否匹配。如果图片匹配,则代码将显示一个对话框,在用户单击对话框中的“确定”后,这两个按钮将不再可用,图片将保持显示,因为用户找到了匹配项。

如果图片不匹配,则隐藏两张图片并使每个按钮可见。最后,在找到或未找到匹配项的两种情况下,代码将 curButtoncurPictureBox 设置回 null 以重新开始整个(选择两张图片)过程。

正如您所指出的,您遇到的一个问题是识别“哪个”PictureBox 属于“哪个”Button。换句话说,我们可以轻松识别在按钮单击事件中单击的 Button,但是,这并没有告诉我们“哪个”PictureBox 与那个 Button 相关联。这可以通过多种方式完成。 Class 甚至带有图片框和按钮的自定义控件当然是合理且不错的选择。这会将按钮和图片框“绑定”在一起,并使图片框属于按钮成为一个有争议的问题。

然而,在这个简单的例子中,我只是创建了一个方法,它接受一个 Button 和 returns 与传入的 Button 相关联的 PictureBox ... 我们将使用按钮 Name 属性 来标识哪个图片框与给定按钮相关联。这种蛮力方法可能看起来像……

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;
  }
}

这将在按钮点击事件中使用。关于按钮单击事件,应该注意制作二十 (20) 个事件(每个按钮一个)会使事情复杂化并创建一堆重复代码。换句话说,单击按钮时执行的“操作”对于所有按钮都是相同的,唯一的区别是单击了哪个按钮以及与该按钮关联的图片框。因此,我们将把所有按钮连接到这个单一事件。

遍历代码将类似于...单击按钮时,代码将获取单击的 Button 对象并将其设置为名为 clickedButton 的变量。然后使用我们上面的方法,我们将获得与该按钮关联的 PictureBox

接下来,代码检查这是单击的第一个按钮还是第二个按钮。如果 curButtonnull,那么,这是第一个被点击的按钮。如果 curButton 不为空,则这是单击的第二个按钮。

单击第一个按钮时,代码只是将两个全局变量设置为 selected 控件并显示图片和隐藏图片按钮。然后代码一直等到用户单击第二个按钮。

单击第二个按钮时,将检查两个图像是否为同一图像。如果图像是相同的图像,那么代码会简单地隐藏这两个按钮并使图片可见,因为用户找到了匹配项。最后,代码将两个全局变量设置为 null 以允许用户开始 select 更多两个按钮。

关于以下代码行Image比较的特别说明…

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

只有当两个图片框都包含相同的 Image 对象时,这种相等性才会起作用。在此示例中,我对两个图片框使用了相同的 Image 对象。如果使用两个不同的 Image 对象使得 Image 对象不同但包含相同的图片,那么上面的代码将失败,因为内存引用显然总是不同的。您可能需要根据图像添加到图片框的方式进行调整。

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;
  }
}