1

I've got a DataGridView that I populate in this way: the even-numbered rows contain "constant" values that are not to be edited by the user. The odd-numbered rows can be edited by the user, but should only contain 0 or 1 characters. If the cell contains a value and the user presses a key, it should first move to the next cell down, and then allow that value to be entered in that next cell. In this way a user can continue pressing a key and the cells below will be populated each time.

I've got this code (based on code from David Hall here: How can I programmatically move from one cell in a datagridview to another?):

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];
    }
}

This works great the first time I enter a val in a cell that already has a value - it moves to the next cell down and the subsequent key press enters the value there. After that, though, it skips one more cell each time. IOW, if I first enter a "2" in the cell at column 5, row 2, it moves to row 3 (good!); then, though, it moves to row 5, skipping row 4. On the next key press it moves to row 8, skipping rows 6 and 7, and so on.

Why would it act this way, and what is the solution?

UPDATE

Okay, based on LarsTech's answer below, I've now got this code:

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];
            }
        }
    }
}

However, now the problem is that if I am in a cell which has a previous value entered, it won't overwrite an old value with the new value being entered. So is there a way to not enter another value in this cell while simultaneously allowing a new value to replace an existing value in the cell?

Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

1 Answers1

1

You are adding more and more keypress events:

e.Control.KeyPress += TextboxNumeric_KeyPress;

without removing the previous keypress event. So it's calling it multiple times.

Try changing it to something like this:

if (columnIndex % 2 == 1) {
  e.Control.KeyPress -= TextboxNumeric_KeyPress;
  e.Control.KeyPress += TextboxNumeric_KeyPress;
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225