Link to home
Start Free TrialLog in
Avatar of BlakeMcKenna
BlakeMcKennaFlag for United States of America

asked on

Moving to the next Column in a DGV using Enter Key???

How can I advance to the next column, same row of a DGV using the Enter/Return Key?
Avatar of mytonytiger
mytonytiger

You can capture the key down event of the datagridview. The programatically select the next cell

    Private Sub DataGridView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown

        If e.KeyCode = Keys.Return Then
            e.Handled = True
            'Code to select next cell goes here


        End If

    End Sub
Here's one example of moving to the next cell:

    Private Sub DataGridView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown

        If e.KeyCode = Keys.Return Then
            e.Handled = True
            SendKeys.Send("{TAB}")
        End If

    End Sub
Avatar of BlakeMcKenna

ASKER

That doesn't work. When I hit the Return/Enter Key, I just stay in the same cell.
Hello,

Try this. Tested it just now and it worked. Might need some tweaking if the active cell is in edit mode.

    Private Sub DataGridView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
        'Check what was pressed and act accordingly
        If e.KeyCode = Keys.Enter Then
            'Resolve the next column index that is visible or it reached the end
            Dim index As Integer = DataGridView1.CurrentCell.ColumnIndex + 1
            Do Until index > (DataGridView1.ColumnCount - 1) OrElse DataGridView1.Columns(index).Visible = True
                index = index + 1
            Loop
            If index > (DataGridView1.ColumnCount - 1) Then
                index = DataGridView1.CurrentCell.ColumnIndex
            End If
            'Activate the new index
            DataGridView1.CurrentCell = DataGridView1.CurrentRow.Cells(index)
            'Tell the grid that you handled the key
            e.Handled = True
        End If

    End Sub


Grtz,
SV
It's still not working! Still stays in the same cell.
Here's my code:

    Private Sub grd_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grd.CellEnter
        Try
            grd.BeginEdit(True)

            Select Case e.ColumnIndex
                Case 2
                    grd.Columns(e.ColumnIndex).DefaultCellStyle.Format = "##.00"
                Case 3
                    grd.Columns(e.ColumnIndex).DefaultCellStyle.Format = "##.00"
                Case 4
                    grd.Columns(e.ColumnIndex).DefaultCellStyle.Format = "##.00"
                Case 5
                    grd.Columns(e.ColumnIndex).DefaultCellStyle.Format = "##.00"
                Case 6
                    grd.Columns(e.ColumnIndex).DefaultCellStyle.Format = "##.00"
                Case 7
                    grd.Columns(e.ColumnIndex).DefaultCellStyle.Format = "##.00"
                Case 8
                    grd.Columns(e.ColumnIndex).DefaultCellStyle.Format = "##.00"
            End Select

            If e.ColumnIndex = 0 Then
                btnDelete.Enabled = True
            Else
                btnDelete.Enabled = False
            End If

        Catch ex As Exception
            strProcedure = "grd_CellEnter()"
            Msg = ex.Message
            ErrorHandler(strModule, strProcedure, Msg)
        End Try
    End Sub

    Private Sub grd_CellLeave(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grd.CellLeave
        Try
            SumCell()

            Select Case e.ColumnIndex
                Case 2
                    grd.CurrentRow.Cells(2).Value = Format(grd.CurrentRow.Cells(2).Value, "##.00")
                Case 3
                    grd.CurrentRow.Cells(3).Value = Format(grd.CurrentRow.Cells(3).Value, "##.00")
                Case 4
                    grd.CurrentRow.Cells(4).Value = Format(grd.CurrentRow.Cells(4).Value, "##.00")
                Case 5
                    grd.CurrentRow.Cells(5).Value = Format(grd.CurrentRow.Cells(5).Value, "##.00")
                Case 6
                    grd.CurrentRow.Cells(6).Value = Format(grd.CurrentRow.Cells(6).Value, "##.00")
                Case 7
                    grd.CurrentRow.Cells(7).Value = Format(grd.CurrentRow.Cells(7).Value, "##.00")
                Case 8
                    grd.CurrentRow.Cells(8).Value = Format(grd.CurrentRow.Cells(8).Value, "##.00")
            End Select

        Catch ex As Exception
            strProcedure = "grd_CellLeave()"
            Msg = ex.Message
            ErrorHandler(strModule, strProcedure, Msg)
        End Try
    End Sub

    Private Sub grd_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grd.CellValueChanged
        Try
            Select Case e.ColumnIndex
                Case 2, 3, 4, 5, 6, 7, 8
                    grd.CurrentRow.Cells(9).Value = CType(grd.Rows(e.RowIndex).Cells(2).Value, Integer) + _
                                                    CType(grd.Rows(e.RowIndex).Cells(3).Value, Integer) + _
                                                    CType(grd.Rows(e.RowIndex).Cells(4).Value, Integer) + _
                                                    CType(grd.Rows(e.RowIndex).Cells(5).Value, Integer) + _
                                                    CType(grd.Rows(e.RowIndex).Cells(6).Value, Integer) + _
                                                    CType(grd.Rows(e.RowIndex).Cells(7).Value, Integer) + _
                                                    CType(grd.Rows(e.RowIndex).Cells(8).Value, Integer)
            End Select

        Catch ex As Exception
            strProcedure = "grd_CellValueChanged()"
            Msg = ex.Message
            ErrorHandler(strModule, strProcedure, Msg)
        End Try
    End Sub

    Private Sub grd_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles grd.KeyDown
        Try
            If e.KeyCode = Keys.Enter Then
                'Resolve the next column index that is visible or it reached the end
                Dim index As Integer = grd.CurrentCell.ColumnIndex + 1
                Do Until index > (grd.ColumnCount - 1) OrElse grd.Columns(index).Visible = True
                    index = index + 1
                Loop
                If index > (grd.ColumnCount - 1) Then
                    index = grd.CurrentCell.ColumnIndex
                End If
                'Activate the new index
                grd.CurrentCell = grd.CurrentRow.Cells(index)
                'Tell the grid that you handled the key
                e.Handled = True
            End If

        Catch ex As Exception

        End Try
    End Sub
End Class
Ok, Lot of code to interprete there;) Could you tell me if it works when you temporariliy remove all other events on the grid. While you're foing so, I'll have another look at your code.

SV
Another question: If you take out the try catch constructions could it be you run into exceptions. If so this could interupt the overall flow of the app.

SV
I did comment out the rest of the Grid Events and it still bombed. If I have multiple rows on the grid, which I do, it just goes to the next row, same column. I want it to move to the next column SAME row.
I tried commenting out the Try Catch's and that didn't effect anything.
Hmm, I pasted your code into my project and found it to act quite reluctantly. What boggled me a little was why you perform the column setup in the cell_enter event. Wouldn't it suffice to do this once during the formload for instance. Same goes for the cell_leave; what are you aiming for there?

Anyway, I think the mentioned events are interfering somehow here. As I mentioned before, my earlier solution does not work correctly when in edit mode. Looking into that but the problem is that when leaving editmode with the enter key the keypress and keydown events are ignored and I can't tell it that I handled the key already, so it just moves down. Here's the new code:

   Private Sub grd_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grd.CellEndEdit
        'Call the move to next cell routine
        MoveToNextCell()
    End Sub

    Private Sub MoveToNextCell()
        'Resolve the next column index that is visible or it reached the end
        Dim index As Integer = grd.CurrentCell.ColumnIndex + 1
        Do Until index > (grd.ColumnCount - 1) OrElse grd.Columns(index).Visible = True
            index = index + 1
        Loop
        If index > (grd.ColumnCount - 1) Then
            index = grd.CurrentCell.ColumnIndex
        End If
        'Activate the new index
        grd.CurrentCell = grd.CurrentRow.Cells(index)
    End Sub

    Private Sub grd_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles grd.KeyDown
        'Check what was pressed and act accordingly
        If e.KeyCode = Keys.Enter Then
            'Call the cell move routine
            MoveToNextCell()
            'Tell the grid that you handled the key
            e.Handled = True
        End If
    End Sub

Going now, good luck and maybe till tomorrow.
SV
What I am trying to do is simple...at least in concept. I have a grid that is basically a timesheet.  It has 9 columns, 7 of which are the days of the week; mon - sun. In the mon - sun columns, I want to enter a number representing hours worked.  So, if I enter a number like 5, I want it to be fomatted like 5.00 or if I enter 6.5, have it come out as 6.50.  Each time I leave a cell, I want to update the entire grid specifically the 7 day columns as well as a Total Column.

That's all I want to do. Of course updating this grid will update a database table as well.
Well, I think the best approach here is to set up a good dataset and table and bind the grid to it. In this dataset set up the columns of the weekdays with datatype double. By doing so it will correctly apply the format to the underlying value.

In the grid set up the columns with format being #.##0.00. You can do this in design time. Now, as for the calculation, I would add an extra column to the datatable with an expression that sums the hours. This would be something like:
D1+D1+D3+D4+D5+D6+D7
(assuming the columns would be called D1, D2 etc)

As a result any change to a value in one of the other columns is automaticly calculated to the summation column. In my opinion a 'cleaner' solution.

Back to the original question on moving one cell to the right. My previously posted comment provides for half the functionality but still doesn't work when a cell is in edit mode. I'm still working on that one.

Success,
SV
SV,

I've actually got the grid working the way I want (calculations of all columns/rows). However, I'm still not getting the cursor to advance to the next column upon hitting enter/return.
Just for clarification, are the calculations done through events or through the expression property now?

As for the movigint to the next column. The earlier presented code should really do the trick. Although when you press enter while being in ener mode it will (unfortunately) still move downward but with the event triggerd also move to the right. I still am  not able to avoid it from moving down after leaving edit mode.

Keep me posted, as I will do too.
SV
thanks for the tidbit!
The code I posted also moves to the next cell when not in edit mode.
ASKER CERTIFIED SOLUTION
Avatar of voordes
voordes

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial