如何使用C#在Visual Studio中的图片框中访问图像的名称

我有一个程序,它使用图片框有16个网格图块,但只使用5个图像,其余的图块只是一个黑色图像。

我希望能够分辨出“用户”点击的图像。

我有一个名为image_Click的方法(对象发送者,EventArgs e)

我在这个方法中有一个if语句,它声明:

if (peckedSquare.BackColor == Color.Black) { System.Diagnostics.Debug.WriteLine("Pecked a black square"); return; } 

这会发送一个String,让我知道何时单击黑色方块。

是否有一种简单的方法可能会说:

//伪代码:

 if (peckedSquare.ImageName == pigeon1.png) { System.Diagnostics.Debug.WriteLine("Pecked Pigeon number 1"); } 

我搜索了我的查询,但我没有找到任何合适的答案。

//编辑我刚刚重新阅读了我的代码。 我使用随机数将每张图片分配到一个图片框中。 我将此随机数作为变量,因此我可以使用该变量来确定单击了哪个图像。 即。

 if (randomNumber == 1) { System.Diagnostics.Debug.WriteLine("Pecked Pigeon number 1"); } 

或者更好

 pigeonSelected = randomNumber + 1 //as I am using an array to store the images System.Diagnostics.Debug.WriteLine("Pecked Pigeon Number {0}", pigeonSelected); 

作为快速和肮脏的解决方案,我会使用Tag属性,黑色瓷砖为null ,其他人为文件路径(即使您的图像来自资源,也始终可用),如下所示:

 if (peckedSquare.Tag == null) { Debug.WriteLine("Pecked a black square"); } else { switch (Path.GetFileName(peckedSquare.Tag.ToString())) { case "pigeon1.png": break; } } 

当然,在创建切片时,您必须在Tag存储文件路径:

 PictureBox tile = new PictureBox(); tile.Image = Image.FromFile(path); // Or another source, of course tile.Tag = path; 

作为替代方案,您甚至可以使用Name属性,每个控件都被命名(主要用于设计器代码集成),但如果您在运行时创建控件,则可以将该值设置为您想要的任何值(不仅仅是有效的标识符)。 与上面相同的用法只需要调用ToString()

如何提高?

请允许我说这个解决方案不是很OOP。 即使没有大的重构,我们也可以做得更好。 请注意,您可以在Tag属性中存储任何所需内容。 一个数字,一个与文件名无关的简单字符串,甚至(可能更好)表示该图像的classenum (将动作委托给该对象)。 这是一个非常原始的例子:

 abstract class Tile { public abstract void Activate(); } sealed class EmptyTile : Tile { public virtual void Activate() { Debug.WriteLine("Pecked a black square"); } } sealed class ImageTile : Tile { public ImageTile(string content) { _content = content; } public virtual void Activate() { Debug.WriteLine(_content); } private string _content; } 

这样在您的点击事件处理程序中,您可以这样做:

 ((Tile)peckedTile.Tag).Activate(); 

无需检查内部或与null进行比较。 不管是否switch ,只是在创建切片时不要忘记放置正确的对象( ImageTileBlackTile )。

使用PictureBox.Load(string)方法从文件加载图像。 然后文件路径将存储在PictureBox.ImageLocation属性中:

对Load方法的调用将覆盖ImageLocation属性,将ImageLocation设置为方法调用中指定的URL值。

所以你可以写例如:

 if (peckedSquare.ImageLocation.EndsWith("pigeon1.png")) { System.Diagnostics.Debug.WriteLine("Pecked Pigeon number 1"); } 

我想你可以做类似以下的事情:

  private List pictures = null; string[] ImageNames = new string[] { "images\\test_1.jpg", "images\\test_2.jpg" }; private void Form1_Load(object sender, EventArgs e) { pictures = new List(); for (var idx = 0; idx < ImageNames.Length; idx++) { pictures.Add(new PictureBox()); pictures[idx].Image = new Bitmap(ImageNames[idx]); pictures[idx].Click += OnClick; // you'll want to set the offset and everything so it shows at the right place Controls.Add(pictures[idx]); } } private void OnClick(object sender, EventArgs eventArgs) { // you'll definitely want error handling here var ImageName = ImageNames[pictures.IndexOf((PictureBox) sender)]; } 

您可以看到,在点击方法中,您将能够获得图像名称,这是您所相信的。

正如其他人所说,你也可以使用“标签”属性,假设你还没有将其用于其他目的。 关于标签的好处是你可以通过表单设计器编辑它,它允许你比我上面使用的自动布局更好地布局。 祝好运!

您可以使用像@Adriano建议的Tag属性执行此类操作:

 public Form1() { InitializeComponent(); pictureBox1.Click += pictureBox_Click; pictureBox2.Click += pictureBox_Click; pictureBox3.Click += pictureBox_Click; // ... pictureBox1.Tag = "picture1.png"; pictureBox2.Tag = "picture2.png"; pictureBox3.Tag = "picture3.png"; } void pictureBox_Click(object sender, EventArgs e) { PictureBox pb = sender as PictureBox; if (pb.BackColor != Color.Black) Debug.WriteLine(pb.Tag.ToString()); else Debug.WriteLine("Black image"); }