9
votes

I'm using a DataGridView in my WinForms application. My main objective is to make the Enter key not move to the next row in the grid. I still want the enter key to validate and end edit mode.

I found this FAQ entry and subclassed DataGridView to override ProcessDialogKey(). If the key pressed is Enter, I call EndEdit(), otherwise I call base.ProcessDialogKey().

It works great, except the CellValidating event isn't fired.

Currently, I'm just manually calling my validation logic before I call EndEdit, but it seems like I'm missing something.

I guess I could call OnCellValidating, but then I'd be worried I'm missing some other event. What I really want is some flavour of EndEdit() that behaves just like pressing enter on the last row of a grid with adding disabled.

5

5 Answers

11
votes

CellValidating doesn't get called until you change the CurrentCell. So the way I kludged around this was to change the CurrentCell, then switch back to the current one.

    protected override bool ProcessDialogKey(Keys keyData)
    {
        if (keyData == Keys.Enter)
        {
            DataGridViewCell currentCell = CurrentCell;
            EndEdit();
            CurrentCell = null;
            CurrentCell = currentCell;
            return true;
        }
        return base.ProcessDialogKey(keyData);
    }
6
votes

JJO's code will crash if cell is in edit mode. Below avoids validation exception:

DataGridViewCell currentCell = AttachedGrid.CurrentCell;
        try
        {             
            AttachedGrid.EndEdit();
            AttachedGrid.CurrentCell = null;
            AttachedGrid.CurrentCell = currentCell;
        }
        catch 
        {
            AttachedGrid.CurrentCell = currentCell;
            AttachedGrid.CurrentCell.Selected = true; 
        }

Source: Kennet Harris's answer here

2
votes

if your DataGridView's DataSource is BindingSouce, do this (put this in your Key processing events):

bds.EndEdit();

if your DataGridView's DataSource is DataTable:

this.BindingContext[dgv.DataSource].EndCurrentEdit();
1
votes

thanks for the solution. my version is a slight different from yours, because when i move to the other cell, and my code returns e.cancel=false in the cell validating event, an error will be generated, says that: "operation did not succeed, because the program cannot commit or quit a cell value change". so i put try catch to overcome this problem.

this is my code:

Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean

    Dim key As Keys = (keyData And Keys.KeyCode)

    If key = Keys.Enter Then
        If MyBase.CurrentCell.ColumnIndex = 1 Then
            Dim iRow As Integer = MyBase.CurrentCell.RowIndex

            MyBase.EndEdit()
            Try
                MyBase.CurrentCell = Nothing
                MyBase.CurrentCell = MyBase.Rows(iRow).Cells(1)
                frmFilter.cmdOk_Click(Me, New EventArgs)
            Catch ex As Exception
            End Try

            Return True
        End If
    End If

    Return MyBase.ProcessDialogKey(keyData)
End Function
0
votes

No, but you can manually fire the CellValidating event. Just create the proper parameters. All events are is a class using the Observer Pattern, they're no different than any other method. If that doesn't work, you can create a KeyPress event on the cell and emulate pressing Enter on the cell, but that may mess with the users UI, just put the carat back where it was.