【问题标题】:How do you access the name of the image in a picturebox in Visual Studio using C#如何使用 C# 在 Visual Studio 中访问图片框中的图像名称
【发布时间】:2014-01-10 05:48:28
【问题描述】:

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

我想知道“用户”点击了哪张图片。

我有一个方法叫做 image_Click(object sender, EventArgs e)

我在这个方法中有一个 if 语句,它指出:

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

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

有没有简单的方法可以说:

//伪代码:

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

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

//编辑 我刚刚重新阅读了我的代码。 我正在使用随机数将每张图片分配给一个图片框方块。 我有这个随机数作为变量,所以我可以使用该变量来确定点击了哪个图像。 IE。

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

【问题讨论】:

  • 你不能那样做。图像存在于内存中,无法跟踪它的来源。
  • PictureBox.ImageLocation 财产?如果使用了PictureBox.Load:“调用 Load 方法将覆盖 ImageLocation 属性,将 ImageLocation 设置为方法调用中指定的 URL 值。”
  • 我假设您只是在这里使用 Windows 窗体 PictureBox。您能否保存对图像的引用,然后将“((PictureBox)sender).Image”属性与您隐藏的图像列表进行比较?
  • @drew_w 我正在使用图像列表数组并从该列表中随机选择图像。所以我只能说如果 ((PictureBox)sender).Image == pigeonPics[0] 然后 pigeon1.png 被点击了?

标签: c# picturebox


【解决方案1】:

作为快速而肮脏的解决方案,我会使用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 进行比较。没有if 也没有switch,只是不要忘记在创建图块时放置正确的对象(ImageTileBlackTile)。

【讨论】:

  • 我认为这个答案最适合我当前的代码。我将使用它,看看它是否有帮助。
  • @pythonReuser 也给了第二个例子的机会。它的可读性更高,也更面向对象(只是一点点)。
【解决方案2】:

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

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

所以你可以写例如:

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

【讨论】:

    【解决方案3】:

    我认为您可以执行以下操作:

        private List<PictureBox> 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<PictureBox>();
            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)];
        }
    

    你可以看到在click方法中你将能够得到图片名称,我相信这就是你要找的。​​p>

    正如其他人所说,假设您尚未将其用于其他目的,您也可以使用“标签”属性。标签的好处是您可能还可以通过表单设计器对其进行编辑,这使您可以比我上面使用的自动布局更好地布置事物。祝你好运!

    【讨论】:

      【解决方案4】:

      您可以使用 @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");
      
      }
      

      【讨论】:

        猜你喜欢
        • 2018-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-24
        • 1970-01-01
        • 2015-02-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多