DataGridView and Focus

I am trying to use the RowValidating event of the DataGridView to Cancel any edits and return focus to the DataGridView. I have created a small application that replicates the problem I am having.

Create a form named "Form1", add a TextBox named "TextBox1", add a DataGridView named "DataGridView1", add a Button named "Button1", then paste in the code below.

Tab into the DataGridView and then type a value in the Test1 column and leave the Test2 column blank. Next, click on the TextBox. The ErrorText will show up on the correct row in the DataGridView, but it no longer has focus. You can click again on the TextBox and you are now out of the DataGridView. This should not happen.

Why does setting Cancel = True during the RowValidating event not work when the user clicks another control on the form Has anyone found a work-around for this

I tried to set focus back to the grid, but that didn't work. I tried to set the CurrentCell in the grid, but that didn't work either.

Public Class Form1

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
DataGridView1.Columns.Add(
"Test1", "Test1")
DataGridView1.Columns.Add(
"Test2", "Test2")
End Sub

Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
Dim dgvRow As DataGridViewRow = DataGridView1.Rows(e.RowIndex)

If dgvRow.Cells("Test2").Value Is Nothing OrElse dgvRow.Cells("Test2").Value.ToString.Trim.Length = 0 Then
DataGridView1.Rows(e.RowIndex).ErrorText = "You must enter a value"
e.Cancel = True
End If
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show(
"Clicked")
End Sub

End Class




Answer this question

DataGridView and Focus

  • rundkaas

    did you find any solution yet

    I have the same problem



  • Edelcio Molina

    It took me a while to find someone with a problem same as mine. :)

    I created a form, similar to Yours, with one DGV and one TextBox. I found out that this issue occures only when trying to leave DGV while cell is in edit mode. In fact validation is fired only once and stops only before CellValidating event.

    Editing -> Click outside the DGV -> CellValidating -> Cancel = true -> STOP

    That is OK, but...

    Editing -> Click outside the DGV -> CellValidating -> Cancel = false -> RowValidating -> HERE - even if you set Cancel = true and stop DGV from losing focus, the next time you try to switch to another control none of the Validation events are fired.

    At first I thought this must have been some kind of bug, but You're the only person describing this kind problem I've found by now. Maybe there is something I'm missing or do not understand. I really hope You found a walkaround other than the one You posted on forum. If you know about any article or forum thread on this issue please let me know.


  • onethird13

    No I have not. I have just dealt with it.

    Not the optimum, but it only happens on rare occasions. When the user goes to save the form, I check to see if any of the rows in my DGV have an error icon in them. If any are found, then I do not allow the save to complete and I force focus back to the DGV.



  • KHaines

    I came up with what I thought would be a work-around.  When you click the TextBox, focus is forced back to the DataGridView.  However, when you click on the Button, the message box is displayed and then focus is put back on the DataGridView.  I need focus to stay in the DataGridView.

    Note:  If you set a breakpoint at the start of the RowValidating code and then click the button and step through the code, the button's code never gets fired.  However, if there is no breakpoint, then the button's code does get fired.

    Here is what I came up with:

    Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
         DataGridView1.Columns.Add(
    "Test1", "Test1")
         DataGridView1.Columns.Add(
    "Test2", "Test2")
    End Sub

    Private Sub DataGridView1_RowValidated(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.RowValidated
         If DataGridView1.Rows(e.RowIndex).ErrorText.Trim.Length > 0 Then
              DataGridView1.Focus()
         End If
    End Sub

    Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
    Dim dgvRow As DataGridViewRow = DataGridView1.Rows(e.RowIndex)

         If dgvRow.Cells("Test2").Value Is Nothing OrElse dgvRow.Cells("Test2").Value.ToString.Trim.Length = 0 Then
              DataGridView1.Rows(e.RowIndex).ErrorText = "You must enter a value"

             
    If DataGridView1.Focused Or DataGridView1.IsCurrentCellInEditMode Then
                   e.Cancel = True
              Else
                   e.Cancel = False
              End If
         End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
         MessageBox.Show(
    "Clicked")
    End Sub

    End Class



  • jrg123

    As you can tell, this thread is a little old and there have been no responses. I tried to lay everything out for an easy ability to replicate the situation, but I haven't gotten any replies.

    I have yet to find any way to deal with this aside from just living with it. I have my form's save code look through each row of the grid to see if there are any errors and if so, I do not let the save continue. Not the perfect validation, but it works.



  • DataGridView and Focus