问题
I have a program which has 16 grid tiles using picturebox but only uses 5 images, the rest of the tiles are just a black image.
I would like to be able to tell which image the 'user' clicks on.
I have a method called image_Click(object sender, EventArgs e)
I have an if statement inside this method that states:
if (peckedSquare.BackColor == Color.Black)
{
System.Diagnostics.Debug.WriteLine("Pecked a black square");
return;
}
This sends a String that lets me know when a black square has been clicked.
Is there an easy way to perhaps say:
//pseudo code:
if (peckedSquare.ImageName == pigeon1.png)
{
System.Diagnostics.Debug.WriteLine("Pecked Pigeon number 1");
}
I have googled my query but I have not found any suitable answers.
//EDIT I have just re-read my code. I was assigning each picture to a picturebox square using a randomnumber. I had this random number as a variable, so I can just use that variable to determine which image was clicked. ie.
if (randomNumber == 1)
{
System.Diagnostics.Debug.WriteLine("Pecked Pigeon number 1");
}
or better than that
pigeonSelected = randomNumber + 1 //as I am using an array to store the images
System.Diagnostics.Debug.WriteLine("Pecked Pigeon Number {0}", pigeonSelected);
回答1:
As quick & dirty solution I would use Tag
property for that, null
for black tiles and file path for the others (and it's always available, even if your image comes from resources), something like this:
if (peckedSquare.Tag == null)
{
Debug.WriteLine("Pecked a black square");
}
else
{
switch (Path.GetFileName(peckedSquare.Tag.ToString()))
{
case "pigeon1.png":
break;
}
}
Of course when you create tiles you have to store file path in Tag
:
PictureBox tile = new PictureBox();
tile.Image = Image.FromFile(path); // Or another source, of course
tile.Tag = path;
As alternative you may even use Name
property for this, each control is named (primary for designer-code integration) but if you create controls at run-time you can set that value to anything you want (not only valid identifiers). Same usage as above just no need to call ToString()
.
How to Improve?
Please let me say this solution is not very OOP. Even without a big refactoring we can do little bit better. Note that you can store whatever you want in Tag
property. A number, a simple string unrelated to file name or even (maybe better) a class
or an enum
that represents that image (to delegate action to that object). This is a very raw example:
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;
}
In this way in your click event handler you can do this:
((Tile)peckedTile.Tag).Activate();
No need to check what's inside or to compare with null
. No if
and no switch
, just don't forget to put proper object (ImageTile
or BlackTile
) when you create tiles.
回答2:
Use PictureBox.Load(string) method to load images from file. Then the file path will be stored in the PictureBox.ImageLocation property:
A call to the Load method will overwrite the ImageLocation property, setting ImageLocation to the URL value specified in the method call.
So you can write for example:
if (peckedSquare.ImageLocation.EndsWith("pigeon1.png"))
{
System.Diagnostics.Debug.WriteLine("Pecked Pigeon number 1");
}
回答3:
I think you could do something like the following:
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)];
}
You can see that in the click method you will be able to get the image name, which is what you are looking for I believe.
As others have said, you can also use the "Tag" property assuming you weren't already using this for some other purpose. The nice thing about tag is you can probably also edit it through the form designer which allows you to lay things out a little more nicely than the automatic layout I used above. Good luck!
回答4:
You can do something like this using the Tag property like @Adriano suggested:
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");
}
来源:https://stackoverflow.com/questions/21031319/how-do-you-access-the-name-of-the-image-in-a-picturebox-in-visual-studio-using-c