Переопределение события SelectionChanged - правильный подход. Свойство CurrentCell можно использовать для установки текущей ячейки. Вы хотите что-то вроде этого:
private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
DataGridViewCell currentCell = dataGridView.CurrentCell;
if (currentCell != null)
{
int nextRow = currentCell.RowIndex;
int nextCol = currentCell.ColumnIndex + 1;
if (nextCol == dataGridView.ColumnCount)
{
nextCol = 0;
nextRow++;
}
if (nextRow == dataGridView.RowCount)
{
nextRow = 0;
}
DataGridViewCell nextCell = dataGridView.Rows[nextRow].Cells[nextCol];
if (nextCell != null && nextCell.Visible)
{
dataGridView.CurrentCell = nextCell;
}
}
}
Вам потребуется добавить тест для текущей ячейки, доступной только для чтения, и выполнить цикл, пока следующая ячейка невидима или доступна только для чтения. Вам также нужно проверить, чтобы убедиться, что вы не зацикливаетесь, если все ячейки доступны только для чтения.
Вам придется справиться со случаем, когда индекс отображения также отличается от базового индекса.
Чтобы получить такое поведение только при нажатии клавиши Tab, вам нужно добавить обработчик KeyDown:
private void AlbumChecker_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab)
{
SelectNextEditableCell(DataGridView dataGridView);
}
}
и поместите первый код в этот новый метод.
Возможно, вы захотите проверить, что DataGridView также имеет фокус.