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