1. Computing

A Guide to Programming Validation

There is a whole family of validation events and properties in VB.NET!

By

Validation is the process of checking whether entered data is what it needs to be for the system to work correctly.

There's nothing in .NET that automatically 'validates' input. You have to figure out what your app needs and write the code to detect it. .NET gives you the tools that allow you to place code where it will do the job and then calls it. This Quick Tip is the first of two that show you how to tell .NET how to validate.

The classic example is Zip Code. If you ask users to enter the Zip Code, you should make sure that they don't enter their last name instead. Acres of code are usually devoted to validation and there is no universal 'right' way to do it. It's worth investing in some analysis to decide what's right for your system.

Validation is often placed in a class by itself where it can be updated without updating the whole system. In the case of a Zip Code, validation could be as simple as checking to be sure that the input is a number, or it could be as complex as comparing the entered code with one derived from a GIS search. For common requirements like Zip Code, your shop may have a standard in-house validation DLL that you should include in your project. Your shop might also be using the Microsoft Enterprise Library. One of the seven "functional application blocks" in that free resource provides validation.

Web pages have a special problem with validation because the entire form is sent to the server. If the server performs validation, the user must wait for an entire round-trip to see and correct errors. But validating only on the client will let even a slightly technical user simply avoid the validation (Or worse. Some injection attacks are based on sending code through input fields.) Most authorities (such as my Apress book, Pro ASP.NET 4 in VB) recommend that for web pages, "you always include server-side validation in your code."

Windows forms controls that have a CausesValidation property can fire a whole family of events when the focus shifts from the control. Microsoft calls this "implicit validation" because the events are fired "implicitly" by .NET. Microsoft refers to coding a call to the Validate or ValidateChildren method as "explicit validation". This tip focuses mainly on "implicit" validation. Part two, at this link, focuses on explicit validation.

Keep in mind that CausesValidation = True is the default. If you don't want the events shown below to fire, you have to set it to False.

The exact sequence of the events depends on whether the keyboard or the mouse is used to change the focus:


 Keyboard     Mouse
(or Tab)     (or Focus in code)

1. Enter      1. Enter

2. GotFocus   2. GotFocus

              3. LostFocus <-

3. Leave      4. Leave

4. Validating 5. Validating

5. Validated  6. Validated

6. LostFocus               <-

Not all of these events will fire all the time. Because validation works through the interaction of several different properties and methods, it's not always clear which events actually will fire. Console.WriteLine is a good way to check.


Private Sub ComboBox1_LostFocus(
    ByVal sender As Object,
    ByVal e As System.EventArgs
    ) Handles ComboBox1.LostFocus
    i += 1
    Console.WriteLine(i.ToString &
        ": Handling LostFocus Event.")
End Sub

With a simple form consisting of a ComboBox and a Button, everything looks normal:

--------
Click Here to display the illustration
--------

But if the ComboBox is the only control in the form, it doesn't look so normal anymore. It's always a good idea to make sure how things really work. (In my own testing, I've discovered that different events are triggered while debugging in single-step mode. Using Console.WriteLine is a lot more foolproof.)

--------
Click Here to display the illustration
--------

For Windows Forms, validation is normally done in the Validating event. (Surprise, surprise!)


Imports System.Text.RegularExpressions
Public Class ValidationExForm
    Private Sub txtZipCodeIn_Validating(
        ByVal sender As Object,
        ByVal e As System.ComponentModel.CancelEventArgs
        ) Handles txtZipCodeIn.Validating
        If Not IsValidZip(txtZipCodeIn.Text) Then
            ErrorProvider1.SetError(
                txtZipCodeIn, "Incorrect Zip")
            Console.WriteLine("Bad Zip")
            e.Cancel = True
        Else
            Console.WriteLine("Good Zip")
        End If
     End Sub
    Private Function IsValidZip(
        ByRef value As String) As Boolean
        Dim myRegex As New Regex("^\d{5}([\-]\d{4})?$")
        Return myRegex.IsMatch(value)
    End Function
End Class

--------
Click Here to display the illustration
--------

An ErrorProvider control has also been added to the project. You can see a more complex example of the use of ErrorProvider at this link.

Another thing to notice is that the e parameter for the Validating event is System.ComponentModel.CancelEventArgs, not System.EventArgs as in the other events. For this reason, the Validating object is the only one that supports the Cancel property. We'll see why that's important after we discuss AutoValidate.

The form itself supports a property that affects the way validation works in your code: AutoValidate. This property is an enumeration that can have four different values:

  • Disable
  • EnablePreventFocusChange <-Default
  • EnableAllowFocusChange
  • Inherit

(At least some Microsoft documentation states that the default is EnableAllowFocusChange. That is not the case in my testing.)

Notice the statement ...


e.Cancel = True

... in the code. It has the effect of preventing the rest of the events from running. (Validated and LostFocus with the keyboard.) It can also cause a real problem. It can prevent the form from being closed, even with the close button! One way to solve this problem is to add this code in the FormClosing event.


Private Sub ValidationExForm_FormClosing(
    ByVal sender As Object,
    ByVal e As System.Windows.Forms.FormClosingEventArgs
    ) Handles Me.FormClosing
    e.Cancel = False
End Sub

If you don't care if later events are fired, it might be easier to simply not code the e.Cancel = True statement. Or, you can set the AutoValidate property to EnableAllowFocusChange. This also prevents later events from being fired, but it lets you close the form, and click in other controls.

When AutoValidate is set to Disable on the form, you have to use call Validate or ValidateChildren specifically. Part two of discusses this way of validating.

  1. About.com
  2. Computing
  3. Visual Basic
  4. Quick Tips
  5. Validation and VB.NET Implicit Programming

©2014 About.com. All rights reserved.