Results 1 to 10 of 10

Thread: [Resolved] Problem with data-bound controls validation

  1. #1

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    38

    Resolved [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.

  2. #2
    Member fixo's Avatar
    Join Date
    Aug 2011
    Location
    SPb, Russia
    Posts
    45

    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

  3. #3
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,714

    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.

  4. #4

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    38

    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

  5. #5
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,714

    Re: Problem with data-bound controls validation

    Quote Originally Posted by mf12 View Post
    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.

  6. #6

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    38

    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:
    1. Private Sub GenericTextBox_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs)
    2.         If sender.Text.Length = 0 Then
    3.             sender.CausesValidation = False
    4.             Dim currentRow As DataRowView = TryCast(EnsaiosBindingSource.Current, DataRowView)
    5.             currentRow.BeginEdit()
    6.             currentRow(sender.DataBindings.Item("Text").BindingMemberInfo.BindingField) = System.DBNull.Value
    7.             currentRow.EndEdit()
    8.             sender.CausesValidation = True
    9.         End If
    10.     End Sub

    Thank you for your help Kevin.

  7. #7
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,714

    Re: Problem with data-bound controls validation

    Quote Originally Posted by mf12 View Post
    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:
    1. Private Sub GenericTextBox_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs)
    2.         If sender.Text.Length = 0 Then
    3.             sender.CausesValidation = False
    4.             Dim currentRow As DataRowView = TryCast(EnsaiosBindingSource.Current, DataRowView)
    5.             currentRow.BeginEdit()
    6.             currentRow(sender.DataBindings.Item("Text").BindingMemberInfo.BindingField) = System.DBNull.Value
    7.             currentRow.EndEdit()
    8.             sender.CausesValidation = True
    9.         End If
    10.     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

  8. #8

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    38

    Re: Problem with data-bound controls validation

    Quote Originally Posted by kevininstructor View Post
    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.

  9. #9
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,714

    Re: Problem with data-bound controls validation

    Quote Originally Posted by mf12 View Post
    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?

  10. #10

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    38

    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
  •  



Click Here to Expand Forum to Full Width