How do you access the name of the image in a picturebox in Visual Studio using C#

前端 未结 4 1515
花落未央
花落未央 2020-12-12 02:35

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

相关标签:
4条回答
  • 2020-12-12 03:05

    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.

    0 讨论(0)
  • 2020-12-12 03:10

    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!

    0 讨论(0)
  • 2020-12-12 03:10

    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");
    
    }
    
    0 讨论(0)
  • 2020-12-12 03:17

    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");
    }
    
    0 讨论(0)
提交回复
热议问题