Max Max - 1 month ago 13
C# Question

How to prevent going to next row after editing a DataGridViewTextBoxColumn and pressing EnterKey?

I'm working on a program with

DataGridViews
.
In one
DatagridView
there is a
DataGridViewTextBoxColumn
, which is enabled to be edited by the user. When the user is done with typing the numbers into it, he presses ENTER on the keyboard. Now the
DataGridView
does all its
Events
, and after all
Events
, the last thing is the problem.

Everything is done, and Windows is going to Select the next
DataGridViewRow
, and I'm not able to prevent this.

I tried

if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled


in nearly every event I found. Sadly I was only able to Prevent the ENTER key when the
DataGridViewTextBoxColumn
is not in edit mode.

Heres my methode t find the ENTER while in Editing

Adding the Event

private void dgr_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.KeyPress += new KeyPressEventHandler(dgr_KeyPress_NumericTester);
}


And this is the event to accept numeric input only.

private void dgr_KeyPress_NumericTester(object sender, KeyPressEventArgs e)
{
if (!Char.IsDigit(e.KeyChar) && e.KeyChar != 8) e.Handled = true;
}


To explain in detail:

When the user enters a Value, that has some dependings, I would like to give another control the focus, so he is used to correct the dependings.

I also tried it with
DependingControl.Focus()
but the last "enter" is going to be the last thing on the view.

Does someone know how to prevent this?

Answer

Well, I managed to get something working that does what you want (or at least does the hard part, I think you have already done most of the other stuff) but the solution makes my skin crawl.

What I ended up with to "cancel" the enter key event when editing a cell as to use a mixture of the CellEndEdit event and the SelectionChanged event.

I introduced a couple of class level fields that store some state - in particular what row we are in at the end of editing a cell and whether we are stopping a selection changed.

The code looks like this:

public partial class Form1 : Form
{
    private int currentRow;
    private bool resetRow = false;

    public Form1()
    {
        InitializeComponent();

        // deleted out all the binding code of the grid to focus on the interesting stuff

        dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);

        // Use the DataBindingComplete event to attack the SelectionChanged, 
        // avoiding infinite loops and other nastiness.
        dataGridView1.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete);
    }

    void dataGridView1_SelectionChanged(object sender, EventArgs e)
    {
        if (resetRow)
        {
            resetRow = false;
            dataGridView1.CurrentCell = dataGridView1.Rows[currentRow].Cells[0];          
        }
    }

    void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        resetRow = true;
        currentRow = e.RowIndex;
    }

    void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
        dataGridView1.SelectionChanged += new EventHandler(dataGridView1_SelectionChanged);
    }
} 

You'll want to test this thoroughly to make sure it does exactly what you need. I only checked to see that it does stop a row change when pressing enter out of an editing control.

As I said - I'm not too happy with needing to do something like this - it feels quite brittle, and also like it could have weird side effects. But if you must have this behaviour, and you test it well I think this is the only way to do what you want.