1

I have many PictureBoxes with the names picturebox_D1, picturebox_D2... D30.

What I'd like to do is to change the images in those PictureBoxes, but in loop. Something like this, but working

for (int i = 0; i < 30; i++)
{                     
    if (ReceivedDataTextBox.Text[i].ToString()=="1") 
        "pictureBox_D"+i.Image= new Bitmap(@"Pictures\\green.png");
    else 
        "pictureBox_D"+i.Image= new Bitmap(@"Pictures\\red.png");
}

How can I do it?

Chris Pfohl
  • 18,220
  • 9
  • 68
  • 111
Elfoc
  • 3,649
  • 15
  • 46
  • 57

6 Answers6

2

You can use indexing of the parent container's controls to get a Control by name. For example: If your pictureboxes are just put straight on your form (i.e, not in a Panel, GroupBox or other container):

for(int i = 0; i < 30; i++)
{
    ((PictureBox)this.Controls["pictureBox_D" + i.ToString()]).Image = new Bitmap(@"Pictures\\green.png");
}

For nested PictureBoxes (i.e, ones within GroupBoxes or Panels), just take the same approach but on the parent container:

for(int i = 0; i < 30; i++)
{
    ((PictureBox)this.panel1.Controls["pictureBox_D" + i.ToString()]).Image = new Bitmap(@"Pictures\\green.png");
}

On the surface it may seem logical that by just typing in the string you should be able to reference variables, but once you start to delve deeper into C# you'll realize that this isn't really how things work in C#. The code you write into the IDE is compiled, and during that compilation, all the nice things about high level code (variable names, function names..etc) vanish; your "pictureBox_D" string is meaningless once the code is compiled and makes no sense to the compiler.

Jason Larke
  • 5,289
  • 25
  • 28
  • OP stated in first line of his question that PictureBoxes are correctly named – Antonio Bakula Jun 07 '12 at 14:49
  • 1
    Given that the parameters of the question were "I have many PictureBoxes with the names picturebox_D1, picturebox_D2... D30.", I'd say it's logical that they are called that. – Jason Larke Jun 07 '12 at 14:49
  • I think those are the variable names not the picture box names – GETah Jun 07 '12 at 14:52
  • It specifically says "with the names", and it has now been marked as the answer so I guess I interpreted the question correctly *shrug* – Jason Larke Jun 07 '12 at 15:03
0

I had to deal with a similar situation sometime ago where I had variable names var1, var2, ...

The best way I could find to get around having a monster switch case is to use reflection. Given the name of the picture box, you can easily find out the variable itself using reflection. This should work:

// Assuming this is inside the form where the pictures boxes are hosted
for (int i = 0; i < 30; i++){
    FieldInfo field = GetType().GetField("pictureBox_D"+i, flags);
    PictureBox pictureBox = (PictureBox)field.GetValue(this);
    if (ReceivedDataTextBox.Text[i].ToString()=="1") 
        pictureBox.Image= new Bitmap(@"Pictures\\green.png");
    else 
        pictureBox.Image= new Bitmap(@"Pictures\\red.png");
}
GETah
  • 20,922
  • 7
  • 61
  • 103
0

The best way to do this would be to create a PictureBox array and fill it with your pictureboxes like this:

PictureBox[] pictures = {picturebox_D1, picturebox_D2, ...};

then you can iterate over them

foreach(var p in pictures)
{
    p.Image = new Bitmap(@"Pictures\\green.png");
}
Bali C
  • 30,582
  • 35
  • 123
  • 152
0

In your constructor create and set a local Dictionary<string, PictureBox>. Remember, Forms are classes just like any other C# class and should be treated as such.

Instead of for, you can now use foreach and access the .Key and .Value to get the file names and PictureBox objects. This only works because you have such a rigid relationship between PictureBox name and desired picture, however. If the pairing changes, or you ever want to use the same image for two pictures boxes you'd want to change this to a List<Tuple<string, PictureBox>>. That may even be the best want to handle the situation, in fact.

public class Form1 : Form
{
    private Dictionary<string, PictureBox> pictureBoxes;

    public Form1()
    {
        pictureBoxes = new Dictionary<string, PictureBox>()
        {
              {"Pictures\\green.png", pictureBox_D},
              {"Pictures\\blue.png", pictureBox_B},
              // Etcetera
        }
    }
}

When you want to loop over them you do the following:

foreach(var kvp in pictureBoxes)
{
    kvp.Value.Image = new Bitmap(kvp.Key);
}
Chris Pfohl
  • 18,220
  • 9
  • 68
  • 111
0

Very simple solution:

PictureBox mybox = (PictureBox)this.Controls.Find("pictureBox2", true)[0];
cansik
  • 1,924
  • 4
  • 19
  • 39
0

You can use Controls.OfType<PictureBox>() combined with LINQ to get the items you want. In fact, you can probably transform them all into a collection you can use:

var picBoxes = this.Controls
                    .OfType<PictureBox>()
                    .Where(pb => pb.Name.StartsWith("pictureBox_D"))
                    .ToDictionary(pb => int.Parse(pb.Name.Replace("pictureBox_D", string.Empty)));
for(int i = 0; i < picBoxes.Length; i++)
{
    // Do what you need with picBoxes[i]
}

The nice thing is that you can do this once in your constructor (after InitializeComponent is called) and you have this collection to reuse for the rest of the life of the form. This also ensures that should you add any additional PictureBoxes (that follow the same naming convention) you don't need to change anything.

SPFiredrake
  • 3,852
  • 18
  • 26