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.LoadDataGridView1.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
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.LoadDataGridView1.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
Classjrg123
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.