Results 1 to 8 of 8

Thread: DAtaGridView - move to next column automatically

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2010
    Posts
    350

    DAtaGridView - move to next column automatically

    To speed up data entry on a DataGridView the user wants to move to the next cell automatially.
    Say if a 3 character field is expected in a field, after the 3rd character is entered in that cell it will move automatically to the next cell without the user pressing tab.
    How can I accieve this.

    In CellEnter I tried code like this but it's not noving to the next field.

    If col = ColCode Then
    If Len(GridTimesheet(col, row).Value) = 3 Then
    System.Windows.Forms.SendKeys.Send("{TAB}")
    End If
    End If

  2. #2
    Fanatic Member Flashbond's Avatar
    Join Date
    Jan 2013
    Location
    Istanbul
    Posts
    646

    Re: DAtaGridView - move to next column automatically

    Hi!
    "SendKeys" is not my favorite method. Often it causes pain like turning off numlock or some else... Anyway, you may retrive the initial address and move to next column:
    Code:
    Public Class Form1
        Dim tb As TextBox
        Public Sub New()
            MyBase.New()
            InitializeComponent()
            AddHandler dataGridView1.EditingControlShowing, AddressOf Me.dataGridView1_EditingControlShowing
        End Sub
        Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs)
            If (dataGridView1.CurrentCell.ColumnIndex = 0) Then
                tb = CType(e.Control, TextBox)
                AddHandler tb.TextChanged, AddressOf Me.tb_TextChanged
            End If
        End Sub
        Private Sub tb_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim row As Integer = Me.DataGridView1.CurrentCell.RowIndex
            Dim col As Integer = Me.DataGridView1.CurrentCell.ColumnIndex
            Select Case col
                Case 0
                    If Len(tb.Text) = 2 Then
                        Me.DataGridView1.CurrentCell = Me.DataGridView1(col + 1, row)
                    End If
                Case 1
                    If Len(tb.Text) = 3 Then
                        Me.DataGridView1.CurrentCell = Me.DataGridView1(col + 1, row)
                    End If
                Case 2
                    If Len(tb.Text) = 4 Then
                        Me.DataGridView1.CurrentCell = Me.DataGridView1(0, row + 1)
                    End If
            End Select
        End Sub
    End Class
    This is a scenario for a three-column DGV. First column excepts 2 characters, the second 3 and the third does 4.

    Actually there is no CellTextChanged event in DGV. So you must handle this manually. But the main idea is you may think each cell as if it is a textbox because it is actually a textbox. Here, jm explains it beautifully: http://www.vbforums.com/showthread.p...=1#post4000093
    Last edited by Flashbond; Sep 25th, 2013 at 03:08 PM.
    God, are you punishing me because my hair is better than yours? -Jack Donaghy

  3. #3
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: DAtaGridView - move to next column automatically

    In CellEnter I tried code like this
    It couldn't possibly work in that event which is triggered once and once only when the cell is clicked on or selected in any other way. As you mention data entry the value when the event triggers is of zero length. If, on the other hand you enter a cell that has a value of length 3 from a previous entry this would move to the next cell making it impossible to edit once the initial entry is added.

    On the whole I wouldn't recommend automatic movement through a DGV's cells anyway as there is always the possibility that you will inadvertently undermine the complex process of editing completion, validation and value assignment which follows the leaving of a cell in normal circumstances. It is very easy to come unstuck whilst seeking what is a small advantage (if advantage it is since most data entry clerks will expect there to be some kind of 'confirm' key). If you do go for it then it's important that you do so for every column. There is nothing more frustrating and irritating for those who spend their working lives typing stuff in boxes than having different procedures for just some arbitrarily chosen fields.
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2010
    Posts
    350

    Re: DAtaGridView - move to next column automatically

    I do aggree that it is not a good idea to move to the next field automatically but this is what the user wants.
    They used previous software that did this written in VisualFoxPro, I have rewritten it in VB and they are compaining.
    They say data entry using the DataGridView is too slow - they want to be able to move automatically to the next field.

    I tried the previous example and couldn't get it to work.

    I'm strugling to even find out what the user has typed - in the example below I'm just trying to display it in a label.
    I'm not sure I'm using the correct event.
    As the user enters say "ABC", I want to display "A", then display "AB", then display "ABC".

    <code>
    Private Sub GridTimesheet_EditingControlShowing(sender As Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles GridTimesheet.EditingControlShowing
    Dim tb As TextBox
    tb = CType(e.Control, TextBox)
    Label4.Text = tb.Text
    End Sub
    </code>

  5. #5
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,686

    Re: DAtaGridView - move to next column automatically

    No matter if this is a good or bad idea conceptually this code below is close. I took something already done for an example (for treating ENTER as TAB) and tweaked it to work as follows.
    Have 14 or greater characters in the Occupation column while in edit mode end edit, move to the next column.
    By no means would this be considered optimal or w/o issues, instead a place to start.

    Requires a DataGridView on the form

    Code:
    Public Class Form1
        Private mEditRow As Integer = -1
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            DataGridView1.ColumnCount = 4
    
            DataGridView1.Columns(0).Name = "FirstName"
            DataGridView1.Columns(1).Name = "LastName"
            DataGridView1.Columns(2).Name = "Occupation"
            DataGridView1.Columns(3).Name = "Joined"
    
            DataGridView1.Rows.Add(New Object() {"Rod", "Stephens", "Auto detailer", #1/2/2013#.ToShortDateString})
            DataGridView1.Rows.Add(New Object() {"Sergio", "Aragones", "Cartoonist", #1/12/2013#.ToShortDateString})
            DataGridView1.Rows.Add(New Object() {"Eoin", "Colfer", "Author", #11/6/2011#.ToShortDateString})
            DataGridView1.Rows.Add(New Object() {"Terry", "Pratchett", "Developer", #1/2/2013#.ToShortDateString})
    
            DataGridView1.AllowUserToAddRows = False
    
        End Sub
        Private Sub DataGridView1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView1.SelectionChanged
            If mEditRow >= 0 Then
                Dim NewRow As Integer = mEditRow
                mEditRow = -1
                DataGridView1.CurrentCell = DataGridView1.Rows(NewRow).Cells(DataGridView1.CurrentCell.ColumnIndex)
            End If
        End Sub
        Private Sub DataGridView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
            If e.Modifiers = Keys.Control AndAlso e.KeyCode = Keys.Return Then
                'DataGridView1.CurrentRow.Cells(DataGridView1.CurrentCell.ColumnIndex).Value = "oi"
                e.Handled = True
                Exit Sub
            End If
            If e.KeyCode = Keys.Return Then
                If DataGridView1.CurrentRow.Index < DataGridView1.RowCount - 1 AndAlso DataGridView1.CurrentCell.ColumnIndex = DataGridView1.ColumnCount - 1 Then
                    DataGridView1.CurrentCell = DataGridView1(0, DataGridView1.CurrentRow.Index + 1)
                Else
                    Dim CurrentCell As DataGridViewCell = DataGridView1.CurrentCell
                    Dim col As Integer = CurrentCell.ColumnIndex
    
                    col = (col + 1) Mod DataGridView1.Columns.Count
                    CurrentCell = DataGridView1.CurrentRow.Cells(col)
                    DataGridView1.CurrentCell = CurrentCell
                End If
    
                e.Handled = True
            ElseIf e.KeyCode = Keys.Tab Then
                If DataGridView1.CurrentRow.Index < DataGridView1.RowCount - 1 AndAlso DataGridView1.CurrentCell.ColumnIndex = DataGridView1.ColumnCount - 1 Then
                    DataGridView1.CurrentCell = DataGridView1(0, DataGridView1.CurrentRow.Index + 1)
                    e.Handled = True
                Else
                    Dim CurrentCell As DataGridViewCell = DataGridView1.CurrentCell
                    Dim col As Integer = CurrentCell.ColumnIndex
    
                    col = (col + 1) Mod DataGridView1.Columns.Count
                    CurrentCell = DataGridView1.CurrentRow.Cells(col)
                    DataGridView1.CurrentCell = CurrentCell
                End If
            End If
        End Sub
        Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs)
            Dim Length As Int32 = CType(sender, DataGridViewTextBoxEditingControl).Text.Length
            If Length >= 14 Then
                DataGridView1.EndEdit()
                DataGridView1_KeyDown(DataGridView1, New System.Windows.Forms.KeyEventArgs(Keys.Enter))
                e.Handled = True
            End If
        End Sub
        Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            If DataGridView1.Columns("Occupation").Index = DataGridView1.CurrentRow.Cells(DataGridView1.CurrentCell.ColumnIndex).ColumnIndex Then
                Dim tb As TextBox = CType(e.Control, TextBox)
                RemoveHandler tb.KeyDown, AddressOf TextBox1_KeyDown
                AddHandler tb.KeyDown, AddressOf TextBox1_KeyDown
            End If
            mEditRow = DataGridView1.CurrentRow.Index
        End Sub
    End Class

  6. #6
    Fanatic Member Flashbond's Avatar
    Join Date
    Jan 2013
    Location
    Istanbul
    Posts
    646

    Re: DAtaGridView - move to next column automatically

    Quote Originally Posted by DavidGraham167 View Post
    I tried the previous example and couldn't get it to work.
    You should try it with a three-column datagrid named "DataGridView1", see what happens and then modify the code for your needs.
    God, are you punishing me because my hair is better than yours? -Jack Donaghy

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2010
    Posts
    350

    Re: DAtaGridView - move to next column automatically

    Thanks for the sample code, I do understand that it was just a place to start but I am having problems progressing.
    The functionality of pressing Return or Tab and moving to the next cell, and at the end of the row moving to the next row, is what the user wants.
    I found that pressing TAB moved the cursor on two cells, so I removed that code.
    I also found that if I entered a field of 14 characters in the 3rd column it was impossible to edit or change when you went back to that cell.
    Also if I allow rows to be added the user has to press Return twice on each new cell, once to acept the enrty and once to move to the next cell.

    --------------------

    Requires a DataGridView on the form

    Code:
    Public Class Form1
        Private mEditRow As Integer = -1
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            DataGridView1.ColumnCount = 4
    
            DataGridView1.Columns(0).Name = "FirstName"
            DataGridView1.Columns(1).Name = "LastName"
            DataGridView1.Columns(2).Name = "Occupation"
            DataGridView1.Columns(3).Name = "Joined"
    
            DataGridView1.Rows.Add(New Object() {"Rod", "Stephens", "Auto detailer", #1/2/2013#.ToShortDateString})
            DataGridView1.Rows.Add(New Object() {"Sergio", "Aragones", "Cartoonist", #1/12/2013#.ToShortDateString})
            DataGridView1.Rows.Add(New Object() {"Eoin", "Colfer", "Author", #11/6/2011#.ToShortDateString})
            DataGridView1.Rows.Add(New Object() {"Terry", "Pratchett", "Developer", #1/2/2013#.ToShortDateString})
    
            'DataGridView1.AllowUserToAddRows = False
    
        End Sub
        Private Sub DataGridView1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView1.SelectionChanged
            If mEditRow >= 0 Then
                Dim NewRow As Integer = mEditRow
                mEditRow = -1
                DataGridView1.CurrentCell = DataGridView1.Rows(NewRow).Cells(DataGridView1.CurrentCell.ColumnIndex)
            End If
        End Sub
        Private Sub DataGridView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
            If e.Modifiers = Keys.Control AndAlso e.KeyCode = Keys.Return Then
                 e.Handled = True
                Exit Sub
            End If
            If e.KeyCode = Keys.Return Then
                If DataGridView1.CurrentRow.Index < DataGridView1.RowCount - 1 AndAlso DataGridView1.CurrentCell.ColumnIndex = DataGridView1.ColumnCount - 1 Then
                    DataGridView1.CurrentCell = DataGridView1(0, DataGridView1.CurrentRow.Index + 1)
                Else
                    Dim CurrentCell As DataGridViewCell = DataGridView1.CurrentCell
                    Dim col As Integer = CurrentCell.ColumnIndex
    
                    col = (col + 1) Mod DataGridView1.Columns.Count
                    CurrentCell = DataGridView1.CurrentRow.Cells(col)
                    DataGridView1.CurrentCell = CurrentCell
                End If
    
                e.Handled = True
            'ElseIf e.KeyCode = Keys.Tab Then
            '    If DataGridView1.CurrentRow.Index < DataGridView1.RowCount - 1 AndAlso DataGridView1.CurrentCell.ColumnIndex = DataGridView1.ColumnCount - 1 Then
            '        DataGridView1.CurrentCell = DataGridView1(0, DataGridView1.CurrentRow.Index + 1)
            '        e.Handled = True
            '    Else
            '        Dim CurrentCell As DataGridViewCell = DataGridView1.CurrentCell
            '        Dim col As Integer = CurrentCell.ColumnIndex
    
            '        col = (col + 1) Mod DataGridView1.Columns.Count
            '        CurrentCell = DataGridView1.CurrentRow.Cells(col)
            '        DataGridView1.CurrentCell = CurrentCell
            '    End If
            End If
        End Sub
        Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs)
            Dim Length As Int32 = CType(sender, DataGridViewTextBoxEditingControl).Text.Length
            If Length >= 14 Then
                DataGridView1.EndEdit()
                DataGridView1_KeyDown(DataGridView1, New System.Windows.Forms.KeyEventArgs(Keys.Enter))
                e.Handled = True
            End If
        End Sub
        Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            If DataGridView1.Columns("Occupation").Index = DataGridView1.CurrentRow.Cells(DataGridView1.CurrentCell.ColumnIndex).ColumnIndex Then
                Dim tb As TextBox = CType(e.Control, TextBox)
                RemoveHandler tb.KeyDown, AddressOf TextBox1_KeyDown
                AddHandler tb.KeyDown, AddressOf TextBox1_KeyDown
            End If
            mEditRow = DataGridView1.CurrentRow.Index
        End Sub
    End Class

  8. #8
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: DAtaGridView - move to next column automatically

    I found that pressing TAB moved the cursor on two cells, so I removed that code
    Well yes. Because moving one cell right is the default behaviour for Tab so you'd have been duplicating it.

    I also found that if I entered a field of 14 characters in the 3rd column it was impossible to edit or change when you went back to that cell.
    Well I hate to say I told you so but I did, in Post #3 to be precise.

    Also if I allow rows to be added the user has to press Return twice on each new cell, once to acept the enrty and once to move to the next cell.
    Because you're overriding the natural behaviour of Return which is to move to the next row (or create one if it's not already there and adding is allowed).

    So, you remember when I said ...

    On the whole I wouldn't recommend automatic movement through a DGV's cells
    Are you starting to understand why?
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width