Search code examples
c#arrayspictureboxwindows-forms-designer

c# Windows Forms adding pictureBoxes to an Array


I need to add PictureBox's (pictureBox11 to pictureBox30) to an array.

So instead of adding PictureBox's like this:

PictureBox[] Coins = new PictureBox[20];
Coins[0] = pictureBox11;
...
Coins[19] = pictureBox30;

I wrote a for cycle like this (DOESN'T WORK) :

    for (int i = 11; i < 31; i++)
    {
        for (int j = 0; j < Coins.Length; j++)
        { 
             Coins[j] = (PictureBox)Controls.Find(
                            "pictureBox" + i.ToString(), true)[0];
        }
    }

There might be a small stupid mistake somewhere because I use the same cycle for another thing and it works, idk, maybe I'm just blind and cant see the mistake.

Maybe it is relevant, so I will include the code I am assigning for the array elements:

        for (int i = 0; i < Coins.Length; i++)
        {
            if (player.Bounds.IntersectsWith(Coins[i].Bounds))
            {
                Coins[i].Visible = false;
            }
        }

EVERYTHING works fine if I add them as shown in first code, but it is not very practical.

Why isn't the second code (the for cycle) I wrote working for me?

Is there a better way to add multiple pictureboxes to an array?


Solution

  • I am guessing you are making this more complicated than it has to be. To try and understand better, I assume that when you say I need to add pictureboxes (pictureBox11 to pictureBox30) to an array. that you mean there are 30+ PictureBoxs on your form and each PictureBox uses a naming convention such that each is named “pictureBoxX” where “X” is 1,2,3…30,31. Then you want to get a (consecutive?) group of “PictureBoxes” on the form to make invisible. I hope this is correct.

    To simply make the picture boxes invisible, I do not think an array is needed. Simply loop through the picture boxes and make it invisible if the name matches a string of the form “pictureBoxX “. I used IndexsAreValid method to validate the start and end indexes. It is also used in the code for an array implementation below this code.

    Make PictureBoxes invisible without an array

    private void SetPictureBoxesInvisible(int start, int end) {
      int size = -1;
      string targetString = "";
      if (IndexsAreValid(start, end, out size)) {
        for (int i = start; i < end + 1; i++) {
          try {
            targetString = "pictureBox" + i;
            PictureBox target = (PictureBox)Controls.Find(targetString, true)[0];
            if (target != null) {
              target.Visible = false;
            }
          }
          catch (IndexOutOfRangeException e) {
            return;
          }
        }
      }
    }
    

    If you must have a PictureBox array returned, then the code below should work.

    First, to get an array of PictureBoxs as you want you need an array to store them. But first you need to know how big to make it. From your posted code it appears that you want to get picture boxes 11-30 and put them in an array. So we can get the size from these numbers… i.e. 30-11=19 +1 = 20. That’s about all you need. Simply create the array and loop through all the picture boxes and grab pictureBox11-pictureBox30. When done we can use this array to make these `PictureBoxes” invisible.

    I created a method IsValidPic similar to a tryParse to validate if the given index (1,2,3..30) is valid. If it is out of range, I simply ignore that value. This gives you the ability to grab an individual picture box in case the desired picture boxes are not contiguous. I used a few buttons to test the methods.

    Hope this helps.

    private PictureBox[] GetPictureBoxes(int start, int end) {
      int size = - 1;
      if (IndexsAreValid(start, end, out size)) {
        PictureBox curPic = null;
        PictureBox[] allPics = new PictureBox[size];
        int index = 0;
        for (int i = start; i <= end; i++) {
          if (IsValidPic(i, out curPic)) {
            allPics[index] = curPic;
            index++;
          }
        }
        return allPics;
      }
      else {
        return new PictureBox[0];
      }
    }
    
    private Boolean IndexsAreValid(int start, int end, out int size) {
      if (start < 1 || end < 1) {
        size = -1;
        return false;
      }
      if (start > end) {
        size = -1;
        return false;
      }
      size = end - start + 1;
      return true;
    }
    
    private Boolean IsValidPic(int index, out PictureBox picture) {
      string targetName = "pictureBox" + index;
      try {
        PictureBox target = (PictureBox)Controls.Find(targetName, true)[0];
        if (target != null) {
          picture = target;
          return true;
        }
        picture = null;
        return false;
      }
      catch (IndexOutOfRangeException e) {
        picture = null;
        return false;
      }
    }
    
    private void ResetAll() {
      foreach (PictureBox pb in this.Controls.OfType<PictureBox>()) {
        pb.Visible = true;
      }
    }
    
    private void button1_Click(object sender, EventArgs e) {
      TurnInvisible(2, 3);
    }
    
    private void button3_Click(object sender, EventArgs e) {
      TurnInvisible(11, 30);
    }
    
    private void button4_Click(object sender, EventArgs e) {
      TurnInvisible(1,7);
    }
    
    private void TurnInvisible(int start, int end) {
      PictureBox[] pictureBoxesToChange = GetPictureBoxes(start, end);
      foreach (PictureBox pb in pictureBoxesToChange) {
        if (pb != null)
          pb.Visible = false;
      }
    }
    
    private void button2_Click(object sender, EventArgs e) {
      ResetAll();
    }