我先在这里猜一猜。据我所知,Form 上有二十 (20) 个 PictureBoxes 和二十 (20) 个 Buttons。此外,共有十 (10) 个“不同”图像(图片)。在二十 (20) 个PictureBoxes 中的两个中,十个图像中的每一个都被使用了两次。这些图片随机放入每个图片框内。
目标是让用户选择两个“匹配”的图像,方法是单击一个按钮显示一张图片,然后单击另一个按钮显示第二张图像。如果图像相同,则删除(使不可见)与这些图片关联的按钮,然后保留显示的图片。然后用户再次开始挑选另外两张匹配的图片。
如果用户选择了两 (2) 张不匹配的图片,那么我们希望显示一个对话框,指示图片不匹配,然后,使这些图片不可见并将按钮设置回可见,并允许用户再试一次。一个基本的找两张匹配的图片游戏。
如果是这种情况,那么下面的代码是一种简单的方法。使用的方法取决于创建两 (2) 个全局变量... 1) 一个名为 curButton 的 Button... 这将是用户单击以显示第一个选定图像的第一个按钮。并且 2) 一个名为 curPictureBox 的 PictureBox 将保存与第一个单击按钮相关联的 PictureBox。
最初两个全局变量都是null,这表明用户没有选择第一张图片。一旦用户通过按下二十个按钮中的一个选择第一张图片,代码将设置这两个全局变量以指向选定的Button,并且它关联PictureBox。 ……然后……
当用户点击不同的按钮时,我们会检查curButton是不是null...如果curButton不是null,那么,这意味着用户点击了第二个按钮。此时代码将向用户显示第二次点击按钮的图片,然后检查图片是否匹配。如果图片匹配,则代码将显示一个对话框说明这一点,并且在用户单击对话框中的确定后,这两个按钮将不再可用,并且图片将保持显示,因为用户找到了匹配项。
如果图片不匹配,则隐藏两张图片并使每个按钮可见。最后,在找到或未找到匹配项的两种情况下,代码将 curButton 和 curPictureBox 设置回 null 以重新开始整个(选择两张图片)过程。
正如您所指出的,您遇到的一个问题是确定“哪个”PictureBox 属于“哪个”Button。换句话说,我们可以很容易地识别出在按钮点击事件中被点击的Button,然而,这并不能告诉我们“哪个”PictureBox与那个Button相关联。这可以通过多种方式完成。一个类,甚至一个带有图片框和按钮的自定义控件当然是合理且不错的选择。这会将按钮和图片框“绑定”在一起,并使图片框属于按钮的标识成为一个有争议的问题。
然而,在这个简单的例子中,我只是创建了一个方法,它接受一个Button 并返回与传入的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。
接下来,代码检查这是单击的第一个按钮还是单击的第二个按钮。如果curButton 是null,那么,这是第一个单击的按钮。如果curButton 不为空,则这是单击的第二个按钮。
单击第一个按钮时,代码只需将两个全局变量设置为所选控件并显示图片并隐藏图片按钮。然后代码一直等到用户点击第二个按钮。
单击第二个按钮时,会检查两个图像是否为同一图像。如果图像是相同的图像,那么代码会简单地隐藏这两个按钮并让图片可见,因为用户找到了匹配项。最后,代码将两个全局变量设置为null,以允许用户开始选择另外两个按钮。
关于以下代码行中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;
}
}