Question DataGridView set focus on validated cell in error

geothom

Member
Joined
Aug 31, 2013
Messages
8
Programming Experience
10+
I have a databound DataGridView and all columns are combobox. After the user selects a value from the combobox and focus is lost, I validate the dgv entry against other entries in the same column. If found to be invalid, I need to set focus back on the validated cell not the one that caused lost focus. I can successfully alter the value of the validated cell (to test cell reference only) on error but focus always remains on the cell that I clicked last. i.e. If I change the value in dgv(5,2) then click on dgv(6.2) and the validation of dgv(5,2) returns 'Invalid' the focus remains on dgv(6,2) but the value I set in dgv(5,2) is correct. Code below (set focus is lines 15-17):

Private Sub CellValueChanged(ByVal sender As Object, _
                                 ByVal e As DataGridViewCellEventArgs) _
                                 Handles grdRoster.CellValueChanged

        intGrdRow = grdRoster.CurrentCellAddress.Y
        intGrdCol = grdRoster.CurrentCellAddress.X
        If mblnFormActivated = True Then
            If grdRoster.CurrentCellAddress.Y > 0 And _
                grdRoster.CurrentCellAddress.X > 4 Then
                CellValid = True
                CurrentName = grdRoster.CurrentCell.Value
                CheckPrevEntries()
                If CellValid = True Then
                Else
                    grdRoster.CurrentCell = grdRoster(intGrdCol, intGrdRow)
                    grdRoster.CurrentCell.Selected = False
                    grdRoster(intGrdCol, intGrdRow).Selected = True
                End If
            End If
        End If

    End Sub
    '---------------------------------------------------------------------------------------------------!
    Private Sub CheckPrevEntries()
        '---------------------------------------------------------------------------------------------------!
        Dim NameOccurs As Short
        Dim EnteredStartTime As Date
        Dim EnteredEndTime As Date
        Dim RowStartTime As Date
        Dim RowEndTime As Date
        Dim TimeOverlap As Boolean

        TransPosition = "Start"
        TimeOverlap = False
        NameOccurs = 0

        With grdRoster
            EnteredStartTime = TimeValue(CDate(grdRoster.Item(3, intGrdRow).Value))
            EnteredEndTime = TimeValue(CDate(grdRoster.Item(4, intGrdRow).Value))
            For indX = 0 To (.RowCount - 1)
                If indX <> intGrdRow Then  'Exclude current cell from comparison
                    If grdRoster.Item(intGrdCol, indX).Value = CurrentName Then
                        NameOccurs = NameOccurs + 1
                        RowStartTime = TimeValue(CDate(grdRoster.Item(3, indX).Value))
                        RowEndTime = TimeValue(CDate(grdRoster.Item(4, indX).Value))
                        If (EnteredStartTime >= RowStartTime And EnteredStartTime < RowEndTime) Or (EnteredEndTime > RowStartTime And EnteredEndTime < RowEndTime) Then
                            TimeOverlap = True
                        End If
                    End If
                End If
            Next indX


If TimeOverlap = False Then
            Else
                MessageBox.Show("This entry start/end times conflict with other entries for this person")
                CellValid = False
                Exit Sub
            End If
            If NameOccurs < 2 Then
            Else
                Action = MsgBox("Selected Name already has " & NameOccurs & " shifts for this date - Continue?", MsgBoxStyle.YesNo + MsgBoxStyle.Question, "New Schedule Detail?")
                If Action = MsgBoxResult.No Then
                    CellValid = False
                End If
            End If
        End With
        ChangesMade = True
        cmdSave.Enabled = True

        Exit Sub

LocalError:
        MsgBox("frmRoster FaiLED - CheckPrevEntries: " & TransPosition & ":" & Err.Number & "-" & Err.Description & " ** PLEASE NOTE DETAILS OF THIS ERROR AND REPORT IT - ASAP **", MsgBoxStyle.Critical)
        If TransState = True Then
            mobjConn.RollbackTrans()
            TransState = False
        End If

    End Sub
 
You don't validate on the CellValueChanged event. You use the CellValidating event. That is raised before the Value property changes and, if the data is not valid, you cancel the event and the Value never changes, nor does the cell lose focus. What you want is already built in, if you use the correct event.
 
Thanks for the reply JM. I have all the code in place to do the validations etc. and had it (so I thought) working using the CellValidating event, but on further testing it seems that events are being fired multiple times on one click and on occasion eventually, throw an exception. The Windows Form has a DGV with 10 visible columns all of which have Combobox Columns. It is a work roster. What I need to happen is when the user changes a value (combobox) in columns 5 to 11 (Staff names) it checks other rows (same column) for the name chosen. On certain conditions it should give an 'Error' message and the changed cell should remain in focus. One of the staff names in the list is set to spaces to allow the user to remove an entry and leave it blank. When a new roster is being created the DGV is blank and exceptions are thrown when the name columns are clicked. Based on the info above, can someone please suggest how (and which) events should be coded to achieve my goal. Basically my code logic seems sound, but my handling of the events suck. Also, is there a way to avoid having the user click multiple times to get the dropdown list showing on the combos (DisplayStyle is set to 'Nothing' in design)?
 
If exceptions are being thrown then you need to address those exceptions. We can't help you if we don't know what the exceptions are are what code is generating them.

Have a look at the grid's EditMode property for determining what the user has to do to edit cells.
 
Sorry - got trigger happy and posted b4 I was finished. Have improved things by implementing a 'comboBox.SelectionChangeCommitted' event and now my problem is that events are firing once for every displayed column from the first to the currently selected one - e.g. I click on the cell in Row 0 Column 4 (third visible) then the CellValidating event fires three times thereby displaying any error/warning message multiple times!! Please can someone suggest a solution to this.
 
Back
Top