Почему пропускаются строки?

У меня есть DataGridView, который я заполняю таким образом: строки с четными номерами содержат "постоянные" значения, которые не должны редактироваться пользователем. Нечетные строки могут быть отредактированы пользователем, но должны содержать только 0 или 1 символ. Если ячейка содержит значение и пользователь нажимает клавишу, он должен сначала перейти к следующей ячейке вниз, а затем разрешить ввод этого значения в эту следующую ячейку. Таким образом, пользователь может продолжать нажимать клавишу, и ячейки ниже будут заполняться каждый раз.

У меня есть этот код (основанный на коде от Дэвида Холла здесь: Как я могу программно перейти из одной ячейки в представлении данных в другую?):

private void dataGridViewPlatypus_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    int columnIndex = (((DataGridView)(sender)).CurrentCell.ColumnIndex);
    if (columnIndex % 2 == 1) {
        e.Control.KeyPress += TextboxNumeric_KeyPress;
    } 
}

private void TextboxNumeric_KeyPress(object sender, KeyPressEventArgs e)
{
    TextBox tb = sender as TextBox; 
    if (tb.TextLength >= 1)
    {
        dataGridViewPlatypus.CurrentCell = dataGridViewPlatypus[
            dataGridViewPlatypus.CurrentCell.ColumnIndex, 
            dataGridViewPlatypus.CurrentCell.RowIndex + 1];
    }
}

Это прекрасно работает при первом вводе значения val в ячейку, которая уже имеет значение - она ​​перемещается к следующей ячейке вниз, и последующее нажатие клавиши вводит значение там. Однако после этого он пропускает еще одну ячейку каждый раз. IOW, если я сначала введу "2" в ячейку в столбце 5, строка 2, она переместится в строку 3 (хорошо!); затем, однако, он перемещается в строку 5, пропуская строку 4. При следующем нажатии клавиши он перемещается в строку 8, пропуская строки 6 и 7 и так далее.

Почему так будет действовать, и каково решение?

ОБНОВИТЬ

Хорошо, основываясь на ответе LarsTech ниже, я получил этот код:

private void dataGridViewPlatypus_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
    int columnIndex = (((DataGridView)(sender)).CurrentCell.ColumnIndex);
    if (columnIndex % 2 == 1) {
        e.Control.KeyPress -= TextboxNumeric_KeyPress;
        e.Control.KeyPress += TextboxNumeric_KeyPress;
    }
}

private void TextboxNumeric_KeyPress(object sender, KeyPressEventArgs e) {
    const int LAST_ROW = 11;
    const int LAST_COL = 15;
    TextBox tb = sender as TextBox;
    if (tb.TextLength >= 1) {
        if (dataGridViewPlatypus.CurrentCell.RowIndex != LAST_ROW) {
            dataGridViewPlatypus.CurrentCell = dataGridViewPlatypus[
                dataGridViewPlatypus.CurrentCell.ColumnIndex,
                dataGridViewPlatypus.CurrentCell.RowIndex + 1];
        } else { // on last row
            if (dataGridViewPlatypus.CurrentCell.ColumnIndex != LAST_COL) {
                dataGridViewPlatypus.CurrentCell =
                    dataGridViewPlatypus[dataGridViewPlatypus.CurrentCell.ColumnIndex + 2, 0];
            } else // on last row AND last editable column
            {
                dataGridViewPlatypus.CurrentCell = dataGridViewPlatypus[1, 0];
            }
        }
    }
}

Однако теперь проблема в том, что если я нахожусь в ячейке, в которой было введено предыдущее значение, оно не будет перезаписывать старое значение новым вводимым значением. Так есть ли способ не вводить другое значение в эту ячейку, одновременно позволяя новому значению заменить существующее значение в ячейке?

1 ответ

Решение

Вы добавляете все больше и больше событий нажатия клавиш:

e.Control.KeyPress += TextboxNumeric_KeyPress;

без удаления предыдущего события нажатия клавиши. Так он называет это несколько раз.

Попробуйте изменить это на что-то вроде этого:

if (columnIndex % 2 == 1) {
  e.Control.KeyPress -= TextboxNumeric_KeyPress;
  e.Control.KeyPress += TextboxNumeric_KeyPress;
}
Другие вопросы по тегам