0
votes

I have a DataGridView and I want to iterate through all the cells in the DataGridView capturing the values of surrounding cells. I get the expected out of bounds errors on the margins of the DataGridView but I can't find a way for testing their existence first?

Below, I am storing the selected state of a surrounding cell to a bool array however this cell does not exist, so how would I test for or handle that?

neighbourCells[0] = dgv_Current.Rows[x-1].Cells[y].Selected;

Any help greatly appreciated.

1
Provide iterate code snippet, how x and y variables initiated and how they manipulated.Aria
It is clear if x-1 > dgv_Current.Rows.Count or y > dgv_Current.Rows[x-1].Cells.Count you will get out of bounds error.Aria
I'm not sure I understand you Aria. I know why I am getting out of bounds, I want to know how to handle it or test for it so that I can set it's value in the array to false instead of it bombing out. I was hoping someone might be able to show me how to test for the existence of cells in a DGV prior to the execution of my code snippet.acn

1 Answers

0
votes

I am guessing you may be over complicating this. Your comment…

”but I can't find a way for testing their existence first”

It is difficult to test if something exists IF it “doesn’t exist”! And that is why you will get an Out Of Range error IF you don’t check for these “non-existent” cells surrounding a cell. Obviously, any edge cell is going to fall into this category. Example, for any first column cell it will contain three (3) “non-existent” cells Top Left (TL), bottom left (BL) and Left (L). The same would apply to the last column, TR, BR and R.

Given that these cells will be out “Out Of Range” if we try to get their value… it is important to check for these cells and return something like “OOR” meaning that that surrounding cell “Does not exist.”

I suggest a simple method that takes a cells row and col index and returns a list of strings showing the values of the surrounding cells. For the “non-existent” cells, the string “OOR” (Out of range) is used to represent the non-existent surrounding cells.

To simplify this, I suggest a second method that given a row and column index, it would simply return the cells value. In this method it is trivial to make sure that the given row and col index is within the range of the grid’s rows and columns. It may look something like below…

private string GetCellValue(int row, int col) {
  if (row >= 0 && row < dataGridView1.Rows.Count && col >= 0 && col < dataGridView1.Columns.Count) {
    if (dataGridView1.Rows[row].Cells[col].Value != null)
      return dataGridView1.Rows[row].Cells[col].Value.ToString();
    else
      return "null";
  }
  else {
    return "OOR";
  }
}

First the obvious checks; if the row index is greater than or equal to 0 and the row index is also less than the total number of rows in the grid. Same applies with the column index. If either row index or the col index fails these tests… we know it’s a “non-existent” cell and simply return something like “OOR”. If the row and column indexes are valid, then we simply return the cells value, obviously checking for null cells like the new row.

Given this method it should be fairly easy to get the surrounding values of any cell in the grid. Below, a List<string> is used to collect the surrounding cells values. Given a cells row and column index, would return a list of strings such that each string would list a surrounding cell, Example for the Top Left cell “TL->cell value”, “TR->cell value”, “T->call value”… etc. That means we would need to call the method above eight (8) times, once for TL, TR, T, B, L, R, BL, BR. Adding the returned string to the list of surrounding cells. It may look something like below.

private List<string> GetSurroundingCells(int row, int col) {
   List<string> surroundingCells = new List<string>();
   surroundingCells.Add("T->" + GetCellValue(row - 1, col));
   surroundingCells.Add("TL->" + GetCellValue(row - 1, col - 1));
   surroundingCells.Add("TR->" + GetCellValue(row - 1, col + 1));
   surroundingCells.Add("B->" + GetCellValue(row + 1, col));
   surroundingCells.Add("BL->" + GetCellValue(row + 1, col - 1));
   surroundingCells.Add("BR->" + GetCellValue(row + 1, col + 1));
   surroundingCells.Add("L->" + GetCellValue(row, col - 1));
   surroundingCells.Add("R->" + GetCellValue(row, col + 1));
   return surroundingCells;
}

For testing, a DataGridView with three (3) text columns and multiline TextBox are dropped onto a form. The grids SelectionChanged event is wired up and when fired will use the grids CurrentCell to list the surrounding cells value into the text box. I hope this helps.

private void Form1_Load(object sender, EventArgs e) {
  for (int i = 0; i < 10; i++) {
    dataGridView1.Rows.Add("C0R" + i, "C1R" + i, "C2R" + i);
  }
}

private void dataGridView1_SelectionChanged(object sender, EventArgs e) {
  int row = dataGridView1.CurrentCell.RowIndex;
  int col = dataGridView1.CurrentCell.ColumnIndex;
  List<string> surroundingCellsList = GetSurroundingCells(row, col);
  textBox1.Text = "--- Cell a row: " + row + " col: " + col + " Value: " + GetCellValue(row, col) + Environment.NewLine;
  foreach (string item in surroundingCellsList) {
    textBox1.Text += item + Environment.NewLine;
  }