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
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.