Cell validating event problem.

B

Bob

In a datagridview (vs2005, VB.net) I have two columns that are checkboxes. I
need to check that only one of the two can be checked. Its not permissible
to have the two selected to true, but they can both be false.
I wrote code in the cellvalidating event as follows.
Private Sub Datagrid1_CellValidating(ByVal sender As Object, ByVal e As
System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles
Datagrid1.CellValidating

Me.Datagrid1.Rows(e.RowIndex).ErrorText = ""

If (Datagrid1.Columns(e.ColumnIndex).DataPropertyName = "Cell_1") Or _

(Datagrid1.Columns(e.ColumnIndex).DataPropertyName = "Cell_2") Then

If CBool(Datagrid1("Cell_1", e.RowIndex).Value) = True _

And CBool(Datagrid1("Cell_2", e.RowIndex).Value) = True Then

Me.Datagrid1.Rows(e.RowIndex).ErrorText = "Can't have both values true."

e.Cancel = True

End If

End If

End Sub

Say I checked just one checkbox Cell_1 to start, the code allows the change
to be made. If I then ckeck the second checbox (cell_2), it gives me the
error message but does not return the second checkbox I checked to its
unchecked state. I noticed that when I click on the checkbox to uncheck it
after the e.cancel executed, that click does not change its value, I can
both see in the UI that the value did not change before the cellvalidating
event is called and in the cellvalidating event itself, when I set a
breakpoint after the line that checks and verify the value of
CBool(Datagrid1("Cell_2", e.RowIndex).Value) it remains set to true.



What am I doing wrong? I press the sacep key after the e,cancel and the
message and I get the same problem.

Any help appreciated,

Bob
 
B

Bob

Once I'm in this process after the error text has been set, evn my close
button, that has just a Me.close() in it does not work. The only way to
close the form is to click on the form close
cross in the upper right corner of the form. When I reopen it I can see that
the chages were not comitted to the database, which is fine. Its just that
my UI does not respond correctly and I can't expect my users to get out of
it that way.

Any help would be appreciated.

Bob
 
B

Bart Mermuys

Hi,

Bob said:
In a datagridview (vs2005, VB.net) I have two columns that are checkboxes.
I need to check that only one of the two can be checked. Its not
permissible to have the two selected to true, but they can both be false.
I wrote code in the cellvalidating event as follows.

I think common behaviour is so that the user can't leave the cell once
validation fails and is forced to correct it before he can leave the cell.
You can use the esc key to revert the value. But there is a problem in your
code, you can't use "DataGridView[,].Value" for both CheckBox, only for the
non-editing CheckBox, for the the editing CheckBox you need to use
e.FormattedValue.

(Note, FormattedValue is either a Boolean (ThreeState=false) or a CheckState
(ThreeState=true).

Private Sub Datagrid1_CellValidating(ByVal sender As Object, ByVal e As
System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles
Datagrid1.CellValidating

Me.Datagrid1.Rows(e.RowIndex).ErrorText = ""
Dim otherCheck As Boolean = False

If (Datagrid1.Columns(e.ColumnIndex).DataPropertyName = "Cell_1") Then
otherCheck = CBool(Datagrid1("Cell_2", e.RowIndex).Value)
End If

If (Datagrid1.Columns(e.ColumnIndex).DataPropertyName = "Cell_2") Then
otherCheck = CBool(Datagrid1("Cell_1", e.RowIndex).Value)
End If

If ( otherCheck And CBool(e.FormattedValue) ) Then
Me.Datagrid1.Rows(e.RowIndex).ErrorText = "Can't have both values true."
e.Cancel = True
End If

End Sub


HTH,
Greetings
 
B

Bob

I tried to use the cellvalidating event on another column. What I realize
now is the the e.cancel will prevent the cell from bieng changed or pushed
to the unbderlying database but even when user changes cell back to what it
should be or presses esc and cell comes bacj the error icon remains in the
row selector. You can't change row you're stuck. I,m going to make a really
simple sample with a realy small Access database and post it here soon.

Bob
 
B

Bob

Bart, I adapted your code to my datagridview, works like a charm. I'm going
to revisit the sample mdb that I sent to the newsgroup, I still wonder why
that did not work.
Oh by the way, I had to add an if condition to do the testing in the
cellvalidating only when either of these two checkbox fields gets edited.
otherwise the event does a validation on other types of fields and returns
errors, but that was easy.
I owe you one,
Bob

Bart Mermuys said:
Hi,

Bob said:
In a datagridview (vs2005, VB.net) I have two columns that are
checkboxes. I need to check that only one of the two can be checked. Its
not permissible to have the two selected to true, but they can both be
false.
I wrote code in the cellvalidating event as follows.

I think common behaviour is so that the user can't leave the cell once
validation fails and is forced to correct it before he can leave the cell.
You can use the esc key to revert the value. But there is a problem in
your code, you can't use "DataGridView[,].Value" for both CheckBox, only
for the non-editing CheckBox, for the the editing CheckBox you need to use
e.FormattedValue.

(Note, FormattedValue is either a Boolean (ThreeState=false) or a
CheckState (ThreeState=true).

Private Sub Datagrid1_CellValidating(ByVal sender As Object, ByVal e As
System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles
Datagrid1.CellValidating

Me.Datagrid1.Rows(e.RowIndex).ErrorText = ""
Dim otherCheck As Boolean = False

If (Datagrid1.Columns(e.ColumnIndex).DataPropertyName = "Cell_1") Then
otherCheck = CBool(Datagrid1("Cell_2", e.RowIndex).Value)
End If

If (Datagrid1.Columns(e.ColumnIndex).DataPropertyName = "Cell_2") Then
otherCheck = CBool(Datagrid1("Cell_1", e.RowIndex).Value)
End If

If ( otherCheck And CBool(e.FormattedValue) ) Then
Me.Datagrid1.Rows(e.RowIndex).ErrorText = "Can't have both values true."
e.Cancel = True
End If

End Sub


HTH,
Greetings

End If

End Sub

Say I checked just one checkbox Cell_1 to start, the code allows the
change to be made. If I then ckeck the second checbox (cell_2), it gives
me the error message but does not return the second checkbox I checked to
its unchecked state. I noticed that when I click on the checkbox to
uncheck it after the e.cancel executed, that click does not change its
value, I can both see in the UI that the value did not change before the
cellvalidating event is called and in the cellvalidating event itself,
when I set a breakpoint after the line that checks and verify the value
of CBool(Datagrid1("Cell_2", e.RowIndex).Value) it remains set to true.



What am I doing wrong? I press the sacep key after the e,cancel and the
message and I get the same problem.

Any help appreciated,

Bob
 
B

Bart Mermuys

Hi,

Bob said:
Bart, I adapted your code to my datagridview, works like a charm. I'm
going to revisit the sample mdb that I sent to the newsgroup, I still
wonder why that did not work.
Oh by the way, I had to add an if condition to do the testing in the
cellvalidating only when either of these two checkbox fields gets edited.

Actually i thought about this and the reasoning was that if the validating
cell isn't one of the CheckBoxCell then 'otherCheck' couldn't be True so the
following if statement would fail (because of the AND), but i forgot VB.NET
doesn't use a short-circuiting AND operator by default and therefore CBool
is used on other cells too. It should have been:

....
If ( otherCheck AndAlso CBool(e.FormattedValue) ) Then
....

Anyways, glad you got it working.

Greetings
otherwise the event does a validation on other types of fields and returns
errors, but that was easy.
I owe you one,
Bob

Bart Mermuys said:
Hi,

Bob said:
In a datagridview (vs2005, VB.net) I have two columns that are
checkboxes. I need to check that only one of the two can be checked. Its
not permissible to have the two selected to true, but they can both be
false.
I wrote code in the cellvalidating event as follows.

I think common behaviour is so that the user can't leave the cell once
validation fails and is forced to correct it before he can leave the
cell. You can use the esc key to revert the value. But there is a problem
in your code, you can't use "DataGridView[,].Value" for both CheckBox,
only for the non-editing CheckBox, for the the editing CheckBox you need
to use e.FormattedValue.

(Note, FormattedValue is either a Boolean (ThreeState=false) or a
CheckState (ThreeState=true).

Private Sub Datagrid1_CellValidating(ByVal sender As Object, ByVal e As
System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles
Datagrid1.CellValidating

Me.Datagrid1.Rows(e.RowIndex).ErrorText = ""
Dim otherCheck As Boolean = False

If (Datagrid1.Columns(e.ColumnIndex).DataPropertyName = "Cell_1") Then
otherCheck = CBool(Datagrid1("Cell_2", e.RowIndex).Value)
End If

If (Datagrid1.Columns(e.ColumnIndex).DataPropertyName = "Cell_2") Then
otherCheck = CBool(Datagrid1("Cell_1", e.RowIndex).Value)
End If

If ( otherCheck And CBool(e.FormattedValue) ) Then
Me.Datagrid1.Rows(e.RowIndex).ErrorText = "Can't have both values
true."
e.Cancel = True
End If

End Sub


HTH,
Greetings

End If

End Sub

Say I checked just one checkbox Cell_1 to start, the code allows the
change to be made. If I then ckeck the second checbox (cell_2), it gives
me the error message but does not return the second checkbox I checked
to its unchecked state. I noticed that when I click on the checkbox to
uncheck it after the e.cancel executed, that click does not change its
value, I can both see in the UI that the value did not change before the
cellvalidating event is called and in the cellvalidating event itself,
when I set a breakpoint after the line that checks and verify the value
of CBool(Datagrid1("Cell_2", e.RowIndex).Value) it remains set to true.



What am I doing wrong? I press the sacep key after the e,cancel and the
message and I get the same problem.

Any help appreciated,

Bob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top