[RESOLVED] Form Validation Issues
I am writing an application for my Notary business. I am a Notary Public in Iowa.
I have many types of control on the form. ComboBox (that can be modified), TextBox and MaskedTextBox. I know I can use the TextBoxBase class to cover the TextBox and also the MaskedTextBox, but my validation code is not doing anything. Nothing happens.
I have an ErrorProvider on the form called ErrorProvider. It has the "AutoValidate" option set to "EnableAllowFocusChange". The BlinkStyle is set to AlwaysBlink. All other properties are default.
I have three buttons on the form, too. Reset, Save and Close. Both the Reset and Close buttons are set to CausesValidation = False and the Save button is set to CausesValidation = True.
I need to make sure the "required" fields have a value when the Save button is clicked.
So, I figured I would use the Validated and Validating events of the controls. But, when clicking Save, nothing happens. The ErrorProvider doesnt even show. If I leave the control empty, still nothing happens.
This is my code:
Code:
Private Sub Company_Validated(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Company.Validated, CompanyAddress.Validated, CompanyCity.Validated, CompanyZipCode.Validated, CompanyPhone.Validated, CompanyAddressRemit.Validated, CompanyCityRemit.Validated, CompanyZipCodeRemit.Validated
ErrorProvider.SetError(CType(sender, TextBoxBase), String.Empty)
End Sub
Private Sub Company_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) _
Handles Company.Validating, CompanyAddress.Validating, CompanyCity.Validating, CompanyZipCode.Validating, CompanyPhone.Validating, CompanyAddressRemit.Validating, CompanyCityRemit.Validating, CompanyZipCodeRemit.Validating
Dim ErrorMessage As String = String.Empty
Dim TheField As TextBoxBase = CType(sender, TextBoxBase)
If TypeOf TheField Is MaskedTextBox Then
CType(TheField, MaskedTextBox).TextMaskFormat = MaskFormat.ExcludePromptAndLiterals
End If
If Not IsValid(TheField, ErrorMessage) Then
e.Cancel = True
TheField.Select(0, TheField.Text.Length)
ErrorProvider.SetError(TheField, ErrorMessage)
End If
End Sub
Private Function IsValid(ByVal ControlName As TextBoxBase, ByRef ErrorMessage As String) As Boolean
If String.IsNullOrEmpty(ControlName.Text.ToString) Then
ErrorMessage = "This is a required field."
Return False
Else
ErrorMessage = String.Empty
Return True
End If
End Function
Any ideas on what I am doing wrong?
Re: Form Validation Issues
O so where is any thing being saved? I can't see any code that saves any thing.
Re: Form Validation Issues
Nothing is being saved right now. I am in the process of validating the form before I write the code to save the form to a database.
I have it working now, I cleaned the solution which fixed that issue. However, I have come up against another issue. I have ComboBoxes in my form that are editable, but they are populated with records from an SQL database. If I do not have a value selected, or I type the value which AutoAppends and AutoSuggests, the validation succeeds, but, when I only put in one character instead of two (for the state), I get a NullReferenceException. I want to make sure the drop downs have the valid value in them. My code is below which is working right now, except if you delete a character from the ComboBox, it is not telling me two characters required, it gives a NullReferenceException on this line:
Code:
If String.IsNullOrEmpty(CType(ControlName, ComboBox).SelectedItem.ToString) Then
These are my Validated and Validating events.
Code:
Private Sub Company_Validated(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Company.Validated, CompanyAddress.Validated, CompanyCity.Validated, CompanyZipCode.Validated, CompanyPhone.Validated, CompanyAddressRemit.Validated, CompanyCityRemit.Validated, CompanyZipCodeRemit.Validated
ErrorProvider.SetError(CType(sender, TextBoxBase), String.Empty)
End Sub
Private Sub Company_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) _
Handles Company.Validating, CompanyAddress.Validating, CompanyCity.Validating, CompanyZipCode.Validating, CompanyPhone.Validating, CompanyAddressRemit.Validating, CompanyCityRemit.Validating, CompanyZipCodeRemit.Validating
Dim TheTextBox As TextBoxBase = CType(sender, TextBoxBase)
If TypeOf TheTextBox Is MaskedTextBox Then
CType(TheTextBox, MaskedTextBox).TextMaskFormat = MaskFormat.ExcludePromptAndLiterals
End If
If Not ValidateForm(TheTextBox, ErrorMessage) Then
e.Cancel = True
TheTextBox.Select(0, TheTextBox.Text.Length)
ErrorProvider.SetError(TheTextBox, ErrorMessage)
End If
End Sub
Private Sub CompanyState_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles CompanyState.Validated, CompanyStateRemit.Validated
ErrorProvider.SetError(CType(sender, ComboBox), String.Empty)
End Sub
Private Sub CompanyState_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles CompanyState.Validating, CompanyStateRemit.Validating
Dim TheCombobox As ComboBox = CType(sender, ComboBox)
If Not ValidateForm(TheCombobox, ErrorMessage) Then
e.Cancel = True
TheCombobox.Select(0, TheCombobox.Text.Length)
ErrorProvider.SetError(TheCombobox, ErrorMessage)
End If
End Sub
This is what I have for the validating portion:
Code:
Public ErrorMessage As String = String.Empty
Public Function ValidateForm(ByVal ControlName As Control, ByRef ErrorMessage As String) As Boolean
Try
With ControlName
If TypeOf ControlName Is TextBoxBase Then
If String.IsNullOrEmpty(.Text.ToString) Then
ErrorMessage = "This is a required field."
Return False
ElseIf .Name.Contains("Phone") AndAlso .Text.Length <> 10 Then
ErrorMessage = "The phone number must be 10 digits long."
Return False
ElseIf .Name.Contains("ZipCode") AndAlso .Text.Length < 5 Then
ErrorMessage = "The ZIP code must be a minimum of five digits long."
Return False
ElseIf .Name.Contains("ZipCode") AndAlso .Text.Length > 5 AndAlso .Text.Length < 9 Then
ErrorMessage = "The ZIP + 4 format for the ZIP code must be nine digits long."
Return False
Else
ErrorMessage = String.Empty
Return True
End If
ElseIf TypeOf ControlName Is ComboBox Then
If String.IsNullOrEmpty(CType(ControlName, ComboBox).SelectedItem.ToString) Then
ErrorMessage = "The state must be selected."
Return False
ElseIf .Name.Contains("State") AndAlso .Text.Length <> 2 Then
ErrorMessage = "The state must contain two characters."
Return False
Else
ErrorMessage = String.Empty
Return True
End If
End If
End With
Catch InvalidCastEx As InvalidCastException
MessageBox.Show(InvalidCastEx.Message, _
"Invalid Cast Exception", _
MessageBoxButtons.OK, _
MessageBoxIcon.Error, _
MessageBoxDefaultButton.Button1)
Catch NullRefEx As NullReferenceException
MessageBox.Show(NullRefEx.Message, _
"Null Reference Exception", _
MessageBoxButtons.OK, _
MessageBoxIcon.Error, _
MessageBoxDefaultButton.Button1)
End Try
End Function
Re: Form Validation Issues
You should stick to using the Validating and possibly Validated events. You put code to validate the control in the Validating event handler and, if you want to do something when a control passes validation. you put that code in the Validated event handler.
When the Validating event is raised, you validate the contents of the control and, if it fails, set e.Cancel to True. In your case, you'll want to set the error on the ErrorProvider if validation fails and clear if it passes. If you set e.Cancel to True and AutoFocus is set to EnablePreventFocusChange, the control that failed validation will refuse to lose focus.
When it comes time to save the data, you simply call ValidateChildren and test the result. That will raise the Validating event on every child control, which guarantees that even controls that the user has not visited will be validated. If any control fails validation then ValidateChildren returns False. If it returns True then you know that it's safe to save the data because it's all valid.
Re: Form Validation Issues
Thanks, JM. I am revising right now. It's been a while since I coded and I am rusty. Thanks for the info.