Home  |  FAQ  |  About  |  Contact  |  View Source   
 
SEARCH:
 
BROWSE:
    My Hood
Edit My Info
View Events
Read Tutorials
Training Modules
View Presentations
Download Tools
Scan News
Get Jobs
Message Forums
School Forums
Member Directory
   
CONTRIBUTE:
    Sign me up!
Post an Event
Submit Tutorials
Upload Tools
Link News
Post Jobs
   
   
Home >  Tutorials >  VB.NET >  Validating Input in VB.Net
Add to MyHood
   Validating Input in VB.Net   [ printer friendly ]
Stats
  Rating: 4.14 out of 5 by 7 users
  Submitted: 08/25/02
Richard Holden ()

 
Input Validation in VB.Net
by Richard Holden 8/25/2002

Introduction

Making sure that a user entered correct information in a program is one of the most important things a programmer can do. Without correct data from a user the output can never be correct. Trying to multiply the letter c by 7 ('c'*7) is not going to give you a proper answer if your program survives.
I am going to deal with input validation in text boxes as that is the input method I find myself using the most.

The code used in this tutorial can be found in my Die Roller tool.

There are essentially two different ways to validate input for a text box. You can check the data as it is being entered or as the user leaves the text box. I will cover the later in this tutorial because that is what I used in my code example.

Validation

The first thing to do when validating any data is to decide exactly what input the program should accept. In the case of the Die Roller program I was only concerned with integers.

Let’s look at the code I used for most of the text boxes.

    Private Sub textBoxNumDice_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles textBox4SidedNumDice.Leave,
        textBox6SidedNumDice.Leave, textBox8SidedNumDice.Leave,
        textBox10SidedNumDice.Leave, textBox12SidedNumDice.Leave,
        textBox20SidedNumDice.Leave, textBox30SidedNumDice.Leave,
        textBox100SidedNumDice.Leave, textBoxAnySidedNumDice.Leave

        Dim numDice As Long
        Try
            numDice = System.Convert.ToInt64(sender.Text())
        Catch exp As System.FormatException
            sender.Text() = "1"
        Catch exp As System.OverflowException
            sender.Text() = "1"
        End Try
        If (numDice <= 0) Then
            sender.Text() = "1"
        End If
    End Sub


The first thing we should notice about this function is that it is the handler for the .Leave event for all of the text boxes related to the number of dice being rolled. I used one function to handle all of these text boxes because they all do the same thing; they hold a value for the number of dice that are going to be used to calculate the result. The next thing I do is create a variable numDice as a long to hold the value of the text box. I am using exception handling for this validation so that when a user enters a letter into the text box it will not crash later parts of the program. So we start the exception handling block with a Try statement. We then use the VB function System.Convert.* (* in this case being ToInt64, this function can be used to convert many variable types). This function will throw an exception if the sender.Text (sender is a reference for the text box that called the function, this allowed me to use one function for multiple text boxes) can not be converted to an Int64.

In my function I handle 2 of the exceptions available, I may find that this is not sufficient for complete error handling but it seems to cover all situations of which I can think. The System.FormatException occurs when the data in sender.Text is of a type that can not be converted to an Int64. The System.OverflowException occurs when the value can be converted to a number but the number is too large for an Int64. In both cases I set the sender.Text equal to 1 because that is the default value that makes sense for my application. In this case I have to also handle one more rule for my text boxes. When rolling a dice it doesn't make sense to roll 0 dice so I check for numDice <=0 and if that is true reset sender.text to the default value.

This works for most of the text boxes in my application because the labels make it clear that we want an integer. However, if the appropriate input was not clear we should alert the user to what is needed as in this next function.

    Private Sub buttonSided_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button4Sided.Click, button6Sided.Click,
        button8Sided.Click, button10Sided.Click,
        button12Sided.Click, button20Sided.Click,
        button30Sided.Click, button100Sided.Click,
        buttonAnySided.Click

        Dim numDice As Long
        Dim newResult As String

        Select Case sender.Text()
            .
            .
            .
            Case Else 'User chosen dice
                Dim numSides As Long
                Try
                    numSides = System.Convert.ToInt64(textBoxNumSidesInput.Text())
                Catch exp As System.FormatException
                    If textBoxNumSidesInput.Text() = "" Then
                        textBoxNumSidesInput.Focus()
                    Else
                        MessageBox.Show("Error: Please enter a number.", "Error in Input", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    End If
                    Exit Sub
                Catch exp As System.OverflowException
                    MessageBox.Show("Error: Number is too large, please enter a number < 9,223,372,036,854,775,807", "Error in Input",
                        MessageBoxButtons.OK, MessageBoxIcon.Error)
                    Exit Sub
                End Try
                If (numSides <= 1) Then
                    MessageBox.Show("Error: Use positive numbers greater than 1.", "Error in input", MessageBoxButtons.OK,
                        MessageBoxIcon.Warning)
                    textBoxNumSidesInput.Text() = ""
                    Exit Sub
                End If
                Randomize()
                numDice = textBoxAnySidedNumDice.Text()
                textBoxAnySided.Text() = Int((numDice * numSides) * Rnd() + (numDice * 1))
                newResult = System.Convert.ToString(numDice) + "d" + System.Convert.ToString(numSides) + " Result:"
                        + textBoxAnySided.Text() + Microsoft.VisualBasic.ChrW(13) + Microsoft.VisualBasic.ChrW(10)
        End Select
        textBoxRollResults.AppendText(newResult)
    End Sub


I have removed some of the code for sake of brevity.

In this case we have a text box where the desired input is not as clear. The validation still uses exception handling and the convert function. The exceptions thrown are also the same but they are handled in a slightly different way. If there is a format exception we can have 1 of 2 situations, either the user entered nothing, or they entered text. If they entered nothing we don't want to display an error message, instead we use the textbox .Focus() property to set the focus back to the text box to receive more input. If however the text entered is some character instead of a number we want to send the user a message explaining that we are looking for a number. To do this I used the MessageBox function. The lower bound on this text box happens to be greater than 1 so my if statement handles that situation. The only other weird thing about this function is the Exit Sub command. The Exit Sub command was used because this validation is done when the user has clicked on the Roll button, so we are going to try to generate a random number for them. We don't want to continue generating a random number if they have entered invalid data and so we Exit Sub to bypass execution of the remainder of the function.

As I was writing this tutorial I realized that I could help the user understand what needed to be changed by setting the focus back to the text box with the erroneous data. The new code now looks like this.
    Private Sub buttonSided_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button4Sided.Click, button6Sided.Click,
        button8Sided.Click, button10Sided.Click,
        button12Sided.Click, button20Sided.Click,
        button30Sided.Click, button100Sided.Click,
        buttonAnySided.Click

        Dim numDice As Long
        Dim newResult As String

        Select Case sender.Text()
            .
            .
            .
            Case Else 'User chosen dice
                Dim numSides As Long
                Try
                    numSides = System.Convert.ToInt64(textBoxNumSidesInput.Text())
                Catch exp As System.FormatException
                    If textBoxNumSidesInput.Text() = "" Then
                        textBoxNumSidesInput.Focus()
                    Else
                        textBoxNumSidesInput.Focus()
                        MessageBox.Show("Error: Please enter a number.", "Error in Input", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    End If
                    Exit Sub
                Catch exp As System.OverflowException
                    textBoxNumSidesInput.Focus()
                    MessageBox.Show("Error: Number is too large, please enter a number < 9,223,372,036,854,775,807", "Error in Input",
                        MessageBoxButtons.OK, MessageBoxIcon.Error)
                    Exit Sub
                End Try
                If (numSides <= 1) Then
                    textBoxNumSidesInput.Focus()
                    MessageBox.Show("Error: Use positive numbers greater than 1.", "Error in input", MessageBoxButtons.OK,
                        MessageBoxIcon.Warning)
                    textBoxNumSidesInput.Text() = ""
                    Exit Sub
                End If
                Randomize()
                numDice = textBoxAnySidedNumDice.Text()
                textBoxAnySided.Text() = Int((numDice * numSides) * Rnd() + (numDice * 1))
                newResult = System.Convert.ToString(numDice) + "d" + System.Convert.ToString(numSides) + " Result:"
                        + textBoxAnySided.Text() + Microsoft.VisualBasic.ChrW(13) + Microsoft.VisualBasic.ChrW(10)
        End Select
        textBoxRollResults.AppendText(newResult)
    End Sub


Again code was removed for the sake of brevity. No changes needed to be made in the code that was omitted.

Conclusion

Validating data is not difficult if you have in mind a clear idea of correct input. The main thing to remember is to alert the user to what data you are expecting and why the information they entered is incorrect.

If anyone is interested I will be covering validating user input as it happens in another tutorial.

Return to Browsing Tutorials

Email this Tutorial to a Friend

Rate this Content:  
low quality  1 2 3 4 5  high quality

Reader's Comments Post a Comment
 
Actually, Richard, you should use the Validating event, which occurs before Leave and is the proper event for validation (as the name implies). Support for validation is a part of .NET - embrace it, and don't use the ol' pesky VB ways of doing things (pre VB.NET, that is).
-- Heath Stewart, August 29, 2002
 
According to the .Net help files the events occur in the following order:
Focus events occur in the following order:

Enter
GotFocus
Leave
Validating
Validated
LostFocus

Thank you for letting me know more about the validating event. I'm getting used to VB.Net and so I may still do some things the old VB way.
-- Richard Holden, August 29, 2002
 
Oops, you're right. I must've been thinking about the LostFocus event. At any rate, the Validating event is the way to go.
-- Heath Stewart, August 29, 2002
 
I have changed the code for the validating event. All I changed was the function header and the event that function was handling. Here is the old header.
[cs]
Private Sub validateNumDiceTextBox(ByVal sender As Object, ByVal e As System.EventArgs) Handles textBox4SidedNumDice.Leave,textBox6SidedNumDice.Leave, textBox8SidedNumDice.Leave, textBox10SidedNumDice.Leave, textBox12SidedNumDice.Leave, textBox20SidedNumDice.Leave, textBox30SidedNumDice.Leave, textBox100SidedNumDice.Leave, textBoxAnySidedNumDice.Leave
[/cs]

And here is the new one, thanks Heath for bringing this to my attention.
[cs]
Private Sub validateNumDiceTextBox(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles textBox4SidedNumDice.Validating, textBox6SidedNumDice.Validating, textBox8SidedNumDice.Validating, textBox10SidedNumDice.Validating, textBox12SidedNumDice.Validating, textBox20SidedNumDice.Validating, textBox30SidedNumDice.Validating, textBox100SidedNumDice.Validating, textBoxAnySidedNumDice.Validating
[/cs]

If anyone can see a better way to do the validation please let me know. I'm always ready to learn a better way of doing something.
-- Richard Holden, August 29, 2002
 
Fine tutorial! 5*****
-- David Chao, September 04, 2002
 
Copyright © 2001 DevHood® All Rights Reserved