Home > OS >  When I make a matrix of points in form_load it works, but when i make it in a separate class, and ma
When I make a matrix of points in form_load it works, but when i make it in a separate class, and ma

Time:03-13

So I need to make a matrix of points to spread buttons over an area, I wanted to make a class that has the matrix itself because the buttons wont appear on screen all the time and they will move in the grid etc.

anyway, here`s what the constructor for that class does:


 public Table()
        {

            for (int i = 0; i < 4; i  )
            {
                for (int j = 0; j < 4; j  )
                {

                    _Grid[i, j] = new Point(i * 90, j * 90);


                }
            }
        }

90 is the width of the buttons

then I have a property that allows getting the grid:


 public Point[,] Grid
            {
            get;
            }

then i do the form_load like this:


 private void Form1_Load(object sender, EventArgs e)
        {
            Table tab = new Table();
            Point[,] grid = tab.Grid;

            for (int i = 0; i < 4; i  )
            {
                for (int j = 0; j < 4; j  )
                {

                    Button btn =  new Button();
                    btn.Width = 88;
                    btn.Height = 88;
                    btn.Location = grid[i, j]; // it returns a NullReferernceException here
                    panel1.Controls.Add(btn);

                }
            }   
        }

adding the location gives me a nullreference, but if i copy the code from the constructor and make the grid matrix in form_load get it, it works.(button width and height is 88 so there`s a nice little space between the buttons)

im obviously still learning, and you can see im stuck in the very beginning of this project because i cant even make all the buttons appear where they should.

CodePudding user response:

It's quite a guess, but I suspect you've done something like this in Table

private Point[,] _Grid = new blahblahblah
public Point[,] Grid
        {
        get;
        }

These two things are not referring to the same thing in memory - you've filled _Grid and it's valid object, but the property Grid is referencing some invisible backing store variable created by the compiler; having a name that is similar is not enough to wire them together

  • Change Table to be like:
    public Point[,] Grid { get; } = new blahblahblah
  • Delete any mention of _Grid in favor of Grid

  • Change the constructor so it sets up the array via the property (thus writing values into the invisible backing field created by the compiler):

    Grid[i, j] = new Point(i * 90, j * 90);

And then retrieving tab.Grid will retrieve a populated thing that is not null


Footnote, we name private members like _camelCase, not _PascalCase and if you want to explicitly declare a read only property that gets a class member field, it would look like:

private Point[,] _grid = blahblahblah;
public Point[,] Grid { get { return _grid; }}

Or:

private Point[,] _grid = blahblahblah;
public Point[,] Grid { get => _grid; }

i.e. you have to concretely wire them together by having the prop go and get that field by name, and return it

We can get into "properties should not return arrays" another time :D

  • Related