1

If I take some pictureboxes that already exist and add them to an array, Visual Studio is fine with this. I can say, for example, trees[64].BringToFront();, and it'll bring that picturebox to the front everything's fine.

However, when I use a loop to bring every picturebox in the array to the front from start to finish, it throws an error. Doesn't matter where I start or end, doesn't matter how I do the loop, still gives me the exception.

However, if I use a number instead of an int, even if it's still in the loop, it's fine. I can even tell the for loop to start and end on one arbitrary number and it throws the exception, but if I write the exact same number into the array of pictureboxes (trees[]) it works fine.

All I want to do is use a loop to bring all the pictureboxes to the front, is that just something that isn't possible?

Also, in case you're wondering why the try/catch statement looks like that, it's because the pictureboxes are arranged in an 11x11 grid

( TA0, TB0, TC0 ...
  TA1, TB1, TC1 ...
  TA2, TB2, TC2 ...
  .     .    .
  .     .    .
  .     .    .     )
public partial class Form1 : Form
{
    int[] Cell = new int[121];

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Generate();
    }

    private void Generate()
    {
        var trees = new PictureBox[121];
        Random rnd = new Random();
        int n;

        for (int i = 0; i < 10; i++)
        {
            try
            {
                trees[i] = (PictureBox)Controls.Find("TA" + (i).ToString(), true)[0];
                trees[i + 11] = (PictureBox)Controls.Find("TB" + (i + 1).ToString(), true)[0];
                trees[i + 22] = (PictureBox)Controls.Find("TC" + (i + 1).ToString(), true)[0];
                trees[i + 33] = (PictureBox)Controls.Find("TD" + (i + 1).ToString(), true)[0];
                trees[i + 44] = (PictureBox)Controls.Find("TE" + (i + 1).ToString(), true)[0];
                trees[i + 55] = (PictureBox)Controls.Find("TF" + (i + 1).ToString(), true)[0];
                trees[i + 66] = (PictureBox)Controls.Find("TG" + (i + 1).ToString(), true)[0];
                trees[i + 77] = (PictureBox)Controls.Find("TH" + (i + 1).ToString(), true)[0];
                trees[i + 88] = (PictureBox)Controls.Find("TI" + (i + 1).ToString(), true)[0];
                trees[i + 99] = (PictureBox)Controls.Find("TJ" + (i + 1).ToString(), true)[0];
                trees[i + 110] = (PictureBox)Controls.Find("TK" + (i + 1).ToString(), true)[0];
            }
            catch (IndexOutOfRangeException)
            {
                MessageBox.Show("pictureBox does not exist!");
            }
        }

        for(int idx = 0; idx <= 120; idx++)
        {
            n = rnd.Next(1, 3);
            Cell[idx] = n;
            trees[idx].BringToFront();   
        }
    }
}
ad1Dima
  • 3,075
  • 2
  • 23
  • 36
user374955
  • 11
  • 1

3 Answers3

2

You're only setting 110 PictureBoxes into your array, but looping through 121. Your first for loop needs to go for 1 more iteration - that is, the exit condition should be i < 11, not i < 10.

As is, your code "skips" array positions 10, 21, 32, 43, 54, 65, 76, 87, 98, 109, and 120. If you set a break-point in your code right before your second loop runs, and examine the array, you'll see null values at these positions.

The error is correctly thrown in the second loop, once idx = 10; there is no PictureBox at that position, hence the NullReferenceException

CoolBots
  • 4,159
  • 2
  • 11
  • 26
0

You're leaving gaps in the array.

Think about what happens when i is 0: you set pictureboxes for array elements at indexes 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, and 110. The loop then runs while i is less than (but not equal to) 10. So your last value for is 9, which sets pictureboxes for array elements at 9, 20, 31, 42, 53, 64, 75, 86, 97, 108, 119.

This leave gaps in the array at positions 10, 21, 32, 43, 54, 65, 76, 87, 98, 109, and 120.

You can fix the problem by changing the < to <= or by changing the 10 to an 11.

Joel Coehoorn
  • 362,140
  • 107
  • 528
  • 764
0

Thanks everyone! Yup, definitely derped pretty hard on this one. I was also writing the code in the single most inefficient way possible imo, I just changed the number system to go left to right, top to bottom just going through the numbers 0 to 120 instead of a letter/number coordinate system and that allowed me to do more with the system in less code. (T0, T1, T2... T119, T120) Here's a sample of the Generate() method that gives the basic idea of the changes made under that new system.

Keep in mind, I've updated the code considerably so this is in no way reflective of the fully updated system. Here I was creating animations by layering PictureBoxes on top of one another then using the .BringToFront(); function to bring each PictureBox into view. Currently instead of having 121 PictureBoxes times however many images there are, I use 121 PictureBoxes grand total and change the image on each one. That way I'm not using up an ungodly amount of memory for no real reason.

    var trees = new PictureBox[121];
    Random rnd = new Random;

    for(int idx = 0; idx <= 120; idx++)
    {
    try
    {
    trees[i] = (PictureBox)Controls.Find("T" + (i).ToString(), true)[0];
    }
    catch(IndexOutOfRangeException)
    {
        MessageBox.Show("pictureBox does not exist!");
    }

    Cell[idx] = rnd.Next(1,3)

    if(Cell[idx] == 1)
    {
    trees[idx].BringToFront();
    }
    }

The actual code uses a 2D array (Temp_Record[,] = new int [121, 121]) instead of the array Cell[] so that there can be 121 screens of 121 cells along with a second array of the same size called Master_Record[,] to store the permanent values after they've been finalized. Generate() just assigns each entry a number, at which point it calls a private void called Draw() that goes through the entries, reads the number, then uses a long if statement (don't worry, changing it to a switch statement as I clean things up) going through each number and applying the appropriate image to the PictureBox that corresponds with that cell. The default, 'screen' as I call it is 60, given that's the center if you imagine each 11 by 11 grid of pictureboxes in an 11 by 11 grid. If anyone wants the full code from start to finish I'll post it, it's just considerably longer at this point. (It's a simple top-down open world game)

user374955
  • 11
  • 1