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 ofGrid
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