|
-
Aug 24th, 2011, 06:48 AM
#1
Thread Starter
Member
[Resolved] Problem with data-bound controls validation
Hello,
I'm currently working on a data entry application in VB.NET and I'm using data-bound controls by simply dragging the table from the Data Sources window onto the form. It's my first time doing this, but this will save me quite a bit of time since this table has plenty of fields.
Anyway, my problem is that when I enter an invalid value in a textbox and then delete the text it won't let me select other controls or even close the form!
For example, say I have an Age field in the DB, which is an int and I mistakenly type "," on its textbox. Then I decide I actually want to leave that field blank (considering it allows nulls) so I just delete all of the textbox's contents, after doing so, I'm not able to switch focus to another control or close the form.
Does anyone know how I can prevent this from happening?
Thanks in advance.
Last edited by mf12; Sep 5th, 2011 at 07:51 AM.
-
Aug 24th, 2011, 07:16 AM
#2
Member
Re: Problem with data-bound controls validation
You could do it without extrafluous moves straightforward:
Code:
TextBox1.Text = TextBox1.Text.Replace(","c, "."c)
but better yet to use your own autocomplete usercontrol textbox
wich one is supports your custom data validation or you might
play around "TextBox_KeyPress" event to prevent a bad data formatting input
-
Aug 24th, 2011, 08:50 AM
#3
Re: Problem with data-bound controls validation
The attached VS2008 demonstrates default and modified behavior as you are having issues with, in this project I focus on type Decimal and could easily be another numeric type.
Please note there is no drag-drop of controls data bound to a database but that does not mean it is not relavant to your issue.
Best to run the project and change the ComboBox and checkbox options followed by modifying the data both in a TextBox and DataGridView.
Key areas
The following event determines the behavior based on a ComboBox selection how to handle a value in the TextBox bound to a decimal column when the TextBox is empty.
Code:
Private Sub txtDecimalOne_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
If txtDecimalOne.Text.Equals("") Then
Dim currentRow As DataRowView = TryCast(bsDecimals.Current, DataRowView)
If chkUseNull.Checked Then
currentRow.Row("DecimalOne") = System.DBNull.Value
Else
currentRow.Row("DecimalOne") = 0
End If
End If
End Sub
In the DataGridView for the first decimal column the data is cleansed if it contains invalid characters.
Code:
Private Sub DataGridView1_CellValidating( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms _
.DataGridViewCellValidatingEventArgs) _
Handles DataGridView1.CellValidating
Dim GridView As DataGridView = DataGridView1
Dim cell As DataGridViewCell = GridView.Item(e.ColumnIndex, e.RowIndex)
If cell.IsInEditMode Then
Dim c As Control = GridView.EditingControl
Select Case GridView.Columns(e.ColumnIndex).Name
Case "DecimalOne"
c.Text = NumberCleaner(c.Text)
End Select
End If
End Sub
For the second decimal column in regards to the DataGridView we handled the DataError event of the DataGridView, explain to the user they entered incorrect data and abort changes, restore the prior value.
-
Aug 25th, 2011, 04:28 AM
#4
Thread Starter
Member
Re: Problem with data-bound controls validation
Thanks for the replies.
I have just noticed that this does not happen only when invalid values have been previously entered in the TextBox. If I enter a valid integer value, and then delete it from the textbox, I'm still unable to focus on another control/close the form.
kevininstructor:
I'm using data-bound TextBoxes, not a DataGridView.They were automatically created by VS, if that makes any difference.
I've added the following event handler but it doesn't really make any difference as I'm still unable to switch focus:
Code:
Private Sub H2O_totalTextBox_TextChanged(sender As Object, e As System.EventArgs) Handles H2O_totalTextBox.TextChanged
If H2O_totalTextBox.Text = "" Then
Dim currentRow As DataRowView = TryCast(EnsaiosBindingSource.Current, DataRowView)
currentRow.Row("H2O total") = System.DBNull.Value
End If
End Sub
-
Aug 25th, 2011, 06:21 AM
#5
Re: Problem with data-bound controls validation
 Originally Posted by mf12
Thanks for the replies.
I have just noticed that this does not happen only when invalid values have been previously entered in the TextBox. If I enter a valid integer value, and then delete it from the textbox, I'm still unable to focus on another control/close the form.
kevininstructor:
I'm using data-bound TextBoxes, not a DataGridView.They were automatically created by VS, if that makes any difference.
I've added the following event handler but it doesn't really make any difference as I'm still unable to switch focus:
Code:
Private Sub H2O_totalTextBox_TextChanged(sender As Object, e As System.EventArgs) Handles H2O_totalTextBox.TextChanged
If H2O_totalTextBox.Text = "" Then
Dim currentRow As DataRowView = TryCast(EnsaiosBindingSource.Current, DataRowView)
currentRow.Row("H2O total") = System.DBNull.Value
End If
End Sub
Yes I understand you are not using a DataGridView, the DataGridView is there to allow traversing only and you should not consider the presense of the DataGridView as part of what I was showing. Simply focus on the TextBox. In regards to data bound TextBox issue the idea I was not to bind the TextBox automatically as that is part of the problem, instead manually take control of the binding.
-
Aug 25th, 2011, 10:35 AM
#6
Thread Starter
Member
Re: Problem with data-bound controls validation
Doing it manually would probably be better, yes, but that's exactly what I'm avoiding since I have about 50 different fields on that single table so creating them automatically saves a whole lot of work.
This is what I came up with, probably not the best solution, but it works:
VB.NET Code:
Private Sub GenericTextBox_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) If sender.Text.Length = 0 Then sender.CausesValidation = False Dim currentRow As DataRowView = TryCast(EnsaiosBindingSource.Current, DataRowView) currentRow.BeginEdit() currentRow(sender.DataBindings.Item("Text").BindingMemberInfo.BindingField) = System.DBNull.Value currentRow.EndEdit() sender.CausesValidation = True End If End Sub
Thank you for your help Kevin.
-
Aug 25th, 2011, 11:05 AM
#7
Re: Problem with data-bound controls validation
 Originally Posted by mf12
Doing it manually would probably be better, yes, but that's exactly what I'm avoiding since I have about 50 different fields on that single table so creating them automatically saves a whole lot of work.
This is what I came up with, probably not the best solution, but it works:
VB.NET Code:
Private Sub GenericTextBox_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs)
If sender.Text.Length = 0 Then
sender.CausesValidation = False
Dim currentRow As DataRowView = TryCast(EnsaiosBindingSource.Current, DataRowView)
currentRow.BeginEdit()
currentRow(sender.DataBindings.Item("Text").BindingMemberInfo.BindingField) = System.DBNull.Value
currentRow.EndEdit()
sender.CausesValidation = True
End If
End Sub
Thank you for your help Kevin.
Your welcome for the help.
Might I suggest trying to set Option Strict On. Although your code above works it is late binding meaning if there was a possibilty of an issue with the code having Option Strict On gives you a better chance at correcting it prior to running the app.
So for the code above the following would be fine with Option Strict One
Code:
Private Sub GenericTextBox_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
Dim CurrentBox = DirectCast(sender, TextBox)
If CurrentBox.Text.Length = 0 Then
CurrentBox.CausesValidation = False
Dim currentRow As DataRowView = TryCast(EnsaiosBindingSource.Current, DataRowView)
currentRow.BeginEdit()
currentRow(CurrentBox.DataBindings.Item("Text").BindingMemberInfo.BindingField) = System.DBNull.Value
currentRow.EndEdit()
CurrentBox.CausesValidation = True
End If
End Sub
My original suggestion would then be (for generic usage)
Code:
Private Sub GenericDecimalTextBox_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim CurrentBox = DirectCast(sender, TextBox)
If CurrentBox.Text.Equals("") Then
Dim currentRow As DataRowView = TryCast(bsDecimals.Current, DataRowView)
Dim FieldName As String = CurrentBox.DataBindings.Item("Text") _
.BindingMemberInfo.BindingField
If chkUseNull.Checked Then
currentRow.Row(FieldName) = System.DBNull.Value
Else
currentRow.Row(FieldName) = 0
End If
End If
End Sub
-
Aug 26th, 2011, 07:10 AM
#8
Thread Starter
Member
Re: Problem with data-bound controls validation
 Originally Posted by kevininstructor
Your welcome for the help.
Might I suggest trying to set Option Strict On. Although your code above works it is late binding meaning if there was a possibilty of an issue with the code having Option Strict On gives you a better chance at correcting it prior to running the app.
So for the code above the following would be fine with Option Strict One
Code:
Private Sub GenericTextBox_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
Dim CurrentBox = DirectCast(sender, TextBox)
If CurrentBox.Text.Length = 0 Then
CurrentBox.CausesValidation = False
Dim currentRow As DataRowView = TryCast(EnsaiosBindingSource.Current, DataRowView)
currentRow.BeginEdit()
currentRow(CurrentBox.DataBindings.Item("Text").BindingMemberInfo.BindingField) = System.DBNull.Value
currentRow.EndEdit()
CurrentBox.CausesValidation = True
End If
End Sub
My original suggestion would then be (for generic usage)
Code:
Private Sub GenericDecimalTextBox_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim CurrentBox = DirectCast(sender, TextBox)
If CurrentBox.Text.Equals("") Then
Dim currentRow As DataRowView = TryCast(bsDecimals.Current, DataRowView)
Dim FieldName As String = CurrentBox.DataBindings.Item("Text") _
.BindingMemberInfo.BindingField
If chkUseNull.Checked Then
currentRow.Row(FieldName) = System.DBNull.Value
Else
currentRow.Row(FieldName) = 0
End If
End If
End Sub
Thanks lol, that was some code I had just written in a rush.
Today, after doing some more research, I found this:
http://stackoverflow.com/questions/4...921107#4921107
http://msdn.microsoft.com/en-us/libr...ndp1_v3_topic5
This is the most important part of that stackoverflow response:
Once the data source has been updated (to DBNull), the binding mechanism will attempt to then repopulate the Textbox with the newly updated data source value. When the underlying data source value is DBNull, the value used for the bound control is governed by the Binding class's NullValue property.
So, as a TextBox's Text property is a String and it gets assigned a null value, an error occurs.
The solution is to change the BindigClass' NullValue property and set it to a valid value (i.e. String.Empty).
This is quite easy when we manually add the bindings to a few controls in our code but I wonder if there's a way to do the same with controls and bindings created by the form designer...
Last edited by mf12; Aug 26th, 2011 at 07:14 AM.
-
Aug 26th, 2011, 08:50 AM
#9
Re: Problem with data-bound controls validation
 Originally Posted by mf12
Thanks lol, that was some code I had just written in a rush.
Today, after doing some more research, I found this:
http://stackoverflow.com/questions/4...921107#4921107
http://msdn.microsoft.com/en-us/libr...ndp1_v3_topic5
This is the most important part of that stackoverflow response:
So, as a TextBox's Text property is a String and it gets assigned a null value, an error occurs.
The solution is to change the BindigClass' NullValue property and set it to a valid value (i.e. String.Empty).
This is quite easy when we manually add the bindings to a few controls in our code but I wonder if there's a way to do the same with controls and bindings created by the form designer...
In regards to working with the form designer, I honestly have no idea as I never done things this way, only manually. Have you tried using the generic method?
-
Sep 5th, 2011, 07:53 AM
#10
Thread Starter
Member
Re: [Resolved] Problem with data-bound controls validation
I'm sorry for the delay in replying.
Yes, I am using the generic method and it does work just fine 
I've marked the thread as resolved.
Thank you for your help Kevin.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|