Присвоение значения свойству массива объекта внутри цикла For - PullRequest
0 голосов
/ 03 ноября 2019

Предыстория: я пишу головоломку для школьного задания. У меня есть игра-головоломка, сохраненная в текстовом файле. Теперь я загружаю его в форму, читая из сохраненного текстового файла. В текстовом файле первые две строки - это общее количество строк и столбцов плиток (2d PictureBoxes), а следующие строки - номер строки, номер столбца и индекс изображения каждого PictureBox.

Подход. Я использую двумерный массив ссылок Tile (пользовательский класс управления, который наследует класс PictureBox) и использую вложенный цикл для считывания информации каждой плитки (PictureBoxes), т.е. номер строки, номер столбца и индекс изображения. Класс листов имеет свойства с именами Row, Column и TileType. Я пытаюсь присвоить значение свойству внутри вложенного цикла.

//Tile Class
public class Tile : PictureBox
{
   private int row;
   private int column;
   private int tileType;
   public int Row{get; set;}
   public int Column { get; set; }
   public int TileType { get; set; }
}
public Tile[,] LoadPictureBoxes(string filename)
{
  Tile[,] tile;
  //Read the file 
  if (System.IO.File.Exists(filename) == true)
  {
    StreamReader load = new StreamReader(filename);
    int nRow = int.Parse(load.ReadLine());
    int nCol = int.Parse(load.ReadLine());
    //declare two dimensional array of Tile Reference
    tile = new Tile[nRow, nCol];
    //using nested loop to read each tile's information
    for(int i=0; i < nRow; i++)
    {
      for(int j=0; j < nCol; j++)
      {
        tile[i, j].Row = int.Parse(load.ReadLine());   //gets an exception here
        tile[i, j].Column = int.Parse(load.ReadLine());  //gets an exception here
        tile[i, j].TileType = int.Parse(load.ReadLine());  //gets an exception here
      }
    }
    load.Close();
    return tile;
  }

  return new Tile[0, 0];
}

private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
  DialogResult r = dlgLoad.ShowDialog();

  switch (r)
  {
  case DialogResult.Cancel:
    break;
  case DialogResult.OK:
    string fileName = dlgLoad.FileName;
    Tile[,] tile = LoadPictureBoxes(fileName);
    int leftPos = 100;
    int topPos = 0;
    int height = 100;
    int width = 100;
    int rowCount = 0;
    int columnCount = 0;
    //loop after each row of picturebox is generated
    for (int rowNumber = 0; rowNumber < tile.GetLength(0); ++rowNumber)
    {
      ++rowCount;
      for (int colNumber = 0; colNumber < tile.GetLength(1); ++colNumber)
      {
        ++columnCount;
        Tile pic = new Tile();
        pic.Left = leftPos;
        pic.Top = topPos;
        pic.Height = height;
        pic.Width = width;
        pic.BorderStyle = BorderStyle.Fixed3D;
        pic.SizeMode = PictureBoxSizeMode.StretchImage;
        tile[rowCount, columnCount] = pic;
        pnlLoadGame.Controls.Add(pic);
        leftPos += width;
      }
      topPos += height;
    }
    pnlLoadGame.Size = new Size(100 * rowCount, 100 * columnCount);
    pnlGameScore.Left = 100 + 100 * columnCount;
    break;
  }
}

Проблема: я получаю исключение во время выполнения: System.NullReferenceException: 'Ссылка на объект не установлена ​​на экземпляр объекта.'Есть ли альтернативный способ присвоить значение свойству пользовательского PictureBox?

1 Ответ

1 голос
/ 03 ноября 2019

Ваша проблема возникает потому, что даже если вы определили массив как tile = new Tile[nRow, nCol];, вам все равно нужно инициализировать его элементы перед их использованием. Примерно так:

tile[i, j] = new Tile();

После этого можно безопасно выполнить следующие три строки:

tile[i, j].Row = int.Parse(load.ReadLine());
tile[i, j].Column = int.Parse(load.ReadLine());  
tile[i, j].TileType = int.Parse(load.ReadLine());  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...