0% found this document useful (0 votes)
24 views15 pages

Input Validation and Error Handling

The document discusses validation and error handling in VB.NET data entry controls. It describes how controls can validate user input through built-in properties or custom validation code. The focus events that occur during validation are outlined, including Validating and Validated events. An example is then given of implementing dependent dropdown validation between multiple combo boxes to restrict invalid serial port configuration options.

Uploaded by

Mercy Kitur
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views15 pages

Input Validation and Error Handling

The document discusses validation and error handling in VB.NET data entry controls. It describes how controls can validate user input through built-in properties or custom validation code. The focus events that occur during validation are outlined, including Validating and Validated events. An example is then given of implementing dependent dropdown validation between multiple combo boxes to restrict invalid serial port configuration options.

Uploaded by

Mercy Kitur
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

INPUT VALIDATION AND ERROR HANDLING

VALIDATION
VB.NET Data Entry Controls
Textbox, Combo Box, Button and other controls have inbuilt capabilities that validate what the
user is doing at a given moment. In fact, many controls allow you to tailor what data the user can
enter and so you don’t even have to validate.
However, there are some considerations to make when you use data entry controls, and they
include:
 Is the user allowed in this field?
 Should the field be numeric or alpha, or both?
 If the field is numeric, what are the bounds?
 Is there a minimum length or maximum length to the field?
 Should control characters be allowed?
 Are there any other characters that are not allowed?
 Should the field be validated on a character-by-character basis or when the user leaves
the field?
 Will there be multiple lines to the field?
.NET provides controls that actually allow you to set up many of these parameters as control
properties without writing any validation code. Every visible control that can be written to, can
let you know when it is time to perform any validation. Two events are raised concerning
validation:
i). Validating – this occurs when the control tells you it needs validation.
ii). Validated – this occurs when the control thinks you are finished validating.
NB: There is also a Boolean property called CausesValidation that, if set to false, suppresses
these two events.
Validation events are considered focus events. The focus events occur when a control either gets
the focus attention on a form or loses it. These events occur in a certain order that lets you
determine when to validate. The order is as follows:
 Enter – the cursor enters the control
 Focus – the control gains focus of the keyboard and mouse
 leave – the input focus leaves the control
 validating – the control is currently validating
 Validated – The control is done validating
 LostFocus – the control has completely lost focus
Validating event can either let the subsequent events go on or suppress them. You would
suppress subsequent events if validation code indicated a failure.
Simple Data Entry Controls
The .NET framework has a base class called System. Windows. Forms. Control. This class is
responsible for quite a bit of the functionality of the derived controls such as Button, DataGrid,
GroupBox,ListView, ListControl, TreeView, Label, TextBox, DateTimePicker, MonthCalender,
ScrollableControl among others.
Simple Data Entry
The probably most used control on a form is a Textbox. A few other controls can be used for
data entry. They derive from Control class.
Consider the following example that uses Combo Boxes to choose serial port setup choices as
follows:
Speed Data Parity Stop Control Flow
Length bits
9600 8 Odd 2 NONE
4800 7 Even 1.5 XON/XOFF
2400 6 Mark 1 HARDWARE
5 None
Space
Suppose the serial port can only have the following combinations as the valid choices.
9600, 7, odd, 1
9600, 7 even, 2
9600, 8, none, 1
4800, 6, mark, 1
4800, 7, space, 1
4800, 7, space, 2
2400, 5, odd, 1
2400, 5, even, 1
2400, 5, even, 1.5
2400, 6, odd, 1
If we implement the combo boxes and populate them with the choices without limiting the scope,
there will be no on-the-fly validation as shown below and with the following code.

Public Class Form2


Public Sub New()

' This call is required by the designer.


InitializeComponent()

' Add any initialization after the InitializeComponent() call.


cmbSpeed.DropDownStyle = ComboBoxStyle.DropDownList
cmbSpeed.Items.Add("9,600")
cmbSpeed.Items.Add("4,800")
cmbSpeed.Items.Add("2,400")
cmbSpeed.SelectedIndex = 0
cmbFlow.DropDownStyle = ComboBoxStyle.DropDownList
cmbFlow.Items.Add("NONE")
cmbFlow.Items.Add("XON/XOFF")
cmbFlow.Items.Add("HARDWARE")
cmbFlow.SelectedIndex = 0
cmbLen.DropDownStyle = ComboBoxStyle.DropDownList
cmbLen.Items.Add("7 Bits")
cmbLen.Items.Add("8 Bits")
cmbLen.Items.Add("6 Bits")
cmbLen.Items.Add("5 Bits")
cmbLen.SelectedIndex = 0
cmbParity.DropDownStyle = ComboBoxStyle.DropDownList
cmbParity.Items.Add("ODD")
cmbParity.Items.Add("EVEN")
cmbParity.Items.Add("MARK")
cmbParity.Items.Add("SPACE")
cmbParity.Items.Add("NONE")
cmbParity.SelectedIndex = 0
cmbStop.DropDownStyle = ComboBoxStyle.DropDownList
cmbStop.Items.Add("1")
cmbStop.Items.Add("1.5")
cmbStop.Items.Add("2")
cmbStop.SelectedIndex = 0
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load

End Sub
End Class

Users can make wrong choices. One approach to this problem is writing some code in the event
handler of the Close button to see if the choices the user made are correct. This would entail
plenty of if-then blocks and sanity checks. If something is wrong, you will need to pop up error
message that tells the user what is wrong and how to fix it. the problem with this approach is that
you could go back and forth, with the user making changes and you rejecting them.
The other approach is to force the user choose only those values that make sense. This approach
would guarantee on-the-fly validation that is easy for you and unobtrusive to the user. This
approach would involve the following steps:
 Disable all the ComboBoxes except for the first one and disable the button.
 When user makes a choice, fill in the values for the next combobox and enable it.
 Repeat step 2 until all the choices are made.
 Enable the button.
Let’s implement the above requirements.
Public Class Form1
Public Sub New()

' This call is required by the designer.


InitializeComponent()

' Add any initialization after the InitializeComponent() call.


Me.StartPosition = FormStartPosition.CenterScreen
'Handle the click events for each combo box
AddHandler cmbSpeed.SelectedIndexChanged, AddressOf Speed
AddHandler cmbLen.SelectedIndexChanged, AddressOf DataLen
AddHandler cmbParity.SelectedIndexChanged, AddressOf Parity
AddHandler cmdClose.Click, AddressOf CloseMe
cmbSpeed.DropDownStyle = ComboBoxStyle.DropDownList
cmbSpeed.Items.Add("9,600")
cmbSpeed.Items.Add("4,800")
cmbSpeed.Items.Add("2,400")
cmbSpeed.SelectedIndex = 0
cmbFlow.DropDownStyle = ComboBoxStyle.DropDownList
cmbFlow.Items.Add("NONE")
cmbFlow.Items.Add("XON/XOFF")
cmbFlow.Items.Add("HARDWARE")
cmbFlow.SelectedIndex = 0
End Sub
'Form overrides dispose to clean up the component list.

Private Sub Speed(ByVal Sender As Object, ByVal e As EventArgs)


Select Case (cmbSpeed.Text)
Case "9,600"
cmbLen.Items.Clear()
cmbLen.Items.Add("7 Bits")
cmbLen.Items.Add("8 Bits")
Case "4,800"
cmbLen.Items.Clear()
cmbLen.Items.Add("6 Bits")
cmbLen.Items.Add("7 Bits")
Case "2,400"
cmbLen.Items.Clear()
cmbLen.Items.Add("5 Bits")
cmbLen.Items.Add("6 Bits")
Case "1,200"
cmbLen.Items.Clear()
cmbLen.Items.Add("8 Bits")
End Select
cmbLen.SelectedIndex = 0
End Sub
Private Sub DataLen(ByVal Sender As Object, ByVal e As EventArgs)
Select Case (cmbLen.Text)
Case "5 Bits"
If cmbSpeed.Text = "2,400" Then
cmbParity.Items.Clear()
cmbParity.Items.Add("ODD")
cmbParity.Items.Add("EVEN")
End If
Case "6 Bits"
If cmbSpeed.Text = "4,800" Then
cmbParity.Items.Clear()
cmbParity.Items.Add("MARK")
End If
If cmbSpeed.Text = "2,400" Then
cmbParity.Items.Clear()
cmbParity.Items.Add("ODD")
End If
Case "7 Bits"
If cmbSpeed.Text = "9,600" Then
cmbParity.Items.Clear()
cmbParity.Items.Add("ODD")
cmbParity.Items.Add("EVEN")
End If
If cmbSpeed.Text = "4,800" Then
cmbParity.Items.Clear()
cmbParity.Items.Add("SPACE")
End If
Case "8 Bits"
If cmbSpeed.Text = "9,600" Then
cmbParity.Items.Clear()
cmbParity.Items.Add("NONE")
End If
End Select
cmbParity.SelectedIndex = 0
End Sub
Private Sub Parity(ByVal Sender As Object, ByVal e As EventArgs)
Select Case (cmbParity.Text)
Case "NONE"
If cmbLen.Text = "8 Bits" Then
cmbStop.Items.Clear()
cmbStop.Items.Add("1")
End If
Case "ODD"
If cmbLen.Text = "5 Bits" Then
cmbStop.Items.Clear()
cmbStop.Items.Add("1")
End If
If cmbLen.Text = "6 Bits" Then
cmbStop.Items.Clear()
cmbStop.Items.Add("1")
End If
If cmbLen.Text = "7 Bits" Then
cmbStop.Items.Clear()
cmbStop.Items.Add("1")
End If
Case "EVEN"
If cmbLen.Text = "5 Bits" Then
cmbStop.Items.Clear()
cmbStop.Items.Add("1")
cmbStop.Items.Add("1.5")
End If
If cmbLen.Text = "7 Bits" Then
cmbStop.Items.Clear()
cmbStop.Items.Add("2")
End If
Case "SPACE"
If cmbLen.Text = "7 Bits" Then
cmbStop.Items.Clear()
cmbStop.Items.Add("1")
cmbStop.Items.Add("2")
End If
Case "MARK"
If cmbLen.Text = "6 Bits" Then
cmbStop.Items.Clear()
cmbStop.Items.Add("1")
End If
End Select
cmbStop.SelectedIndex = 0
End Sub
Private Sub CloseMe(ByVal Sender As Object, ByVal e As EventArgs)
Me.Close()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

End Sub
End Class

In this code, user can choose any type of flow control he/she wants. However, when it comes to
other choices, user cannot choose any choice. Starting with the chosen speed, other drop-down
boxes will be filled accordingly to only what is allowed considering the other values.
This is a great way to handle both data input and data validation at the same time. When user
finishes making the choices and clicks the button, the programmer is sure that user choices are
valid. There is no need for any error messages or corrections by the user because he/she is
allowed to choose only what is allowed.
Consider another example that uses TextBox to perform data input validation. Textbox control
has quite a few properties that can be used to set up data validation as user types in values. For
example, one can limit the length that the box will hold or the type of value to pass. Some of the
properties that one can assign to textbox to help in data entry and validation includes:
AcceptsReturn, AcceptsTab, AllowDrop, CanFocus, CharacterCasing, MaxLength, MultiLine,
PasswordChar, TextAlign, WordWrap etc.
Let’s demonstrate some of these properties
Create the following interface with the following controls

Ensure that you set the MultiLine property for textbox multiline true and enlarge it to a
considerable height. Then add the following code.
Public Class Form1
Public Sub New()

' This call is required by the designer.


InitializeComponent()

' Add any initialization after the InitializeComponent() call.


cmbMaxLen.Items.Clear()
cmbMaxLen.Items.Add("5")
cmbMaxLen.Items.Add("10")
cmbMaxLen.Items.Add("15")
cmbMaxLen.Items.Add("20")
AddHandler cmbMaxLen.SelectedIndexChanged, AddressOf Me.ChangeLen
cmbMaxLen.SelectedIndex = 0
txtUpper.CharacterCasing = CharacterCasing.Upper
txtPassword.PasswordChar = "*"c
txtCentered.TextAlign = HorizontalAlignment.Center
txtMultiLine.Multiline = True
txtMultiLine.ScrollBars = ScrollBars.Vertical
txtMultiLine.WordWrap = True
txtMultiLine.AcceptsReturn = True
txtMultiLine.AcceptsTab = True
Me.AcceptButton = cmdClose
AddHandler cmdClose.Click, AddressOf Me.CloseMe
End Sub
Private Sub ChangeLen(ByVal sender As Object, ByVal e As EventArgs)
txtUpper.MaxLength = Convert.ToInt32(cmbMaxLen.Text)
txtPassword.MaxLength = txtUpper.MaxLength
txtCentered.MaxLength = txtUpper.MaxLength
End Sub
Private Sub CloseMe(ByVal sender As Object, ByVal e As EventArgs)
Me.Close()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

End Sub
End Class

If you start playing around with this form you will notice that some restrictions have been
imposed on data entry. For example, Uppercase, password and centered textboxes cannot accept
more than specified characters in the Combobox that specify max length. Also notice that when
enter key is pressed in the Centered textbox, the form unloads because the form’s default
AcceptButton to close button. If you try tabbing, you will notice that once tab enters the
Multiline textbox, it cannot be tabbed out.
Now add the following code in the constructor.
cmbMaxLen.TabIndex = 0
txtUpper.TabIndex = 1
txtPassword.TabIndex = 2
txtMultiLine.TabStop = False
txtCentered.TabIndex = 3
cmdClose.TabIndex = 4

Now notice that tab stop for the MultiLine control has been turned off. This is to enforce the tab
to be used as a real tab in this textbox. Because it would be impossible to tab out of it, there is no
reason to tab into it. The order now changes.
It is also possible to restrict the values that one can allow in a textbox. Let’s modify the form by
adding three more textboxes as shown below.

Then add the following code to the ChangeLen Delegate.


txtMixed.MaxLength = txtUpper.MaxLength
txtNumber.MaxLength = txtUpper.MaxLength
txtAlpha.MaxLength = txtUpper.MaxLength
txtAlpha.CharacterCasing = CharacterCasing.Lower
txtMixed.CharacterCasing = CharacterCasing.Upper
AddHandler txtAlpha.KeyPress, AddressOf Me.InputValidator
AddHandler txtNumber.KeyPress, AddressOf Me.InputValidator
AddHandler txtMixed.KeyPress, AddressOf Me.InputValidator

Add the following code to your class


Private Sub InputValidator(ByVal sender As Object, ByVal e As KeyPressEventArgs)
Dim t As TextBox
If sender.GetType() Is GetType(TextBox) Then
t = CType(sender, TextBox)
If t.Name = txtAlpha.Name Then
'If it is not a letter then disallow the character
If (Not Char.IsLetter(e.KeyChar) And e.KeyChar <>
Microsoft.VisualBasic.ChrW(8)) Then
e.Handled = True
End If
End If
If t.Name = txtNumber.Name Then
'If it is not a letter then disallow the character
If (Not Char.IsNumber(e.KeyChar) And e.KeyChar <>
Microsoft.VisualBasic.ChrW(8)) Then
e.Handled = True
End If
End If
If t.Name = txtMixed.Name Then
'Allow only 0-9,A-F,<>?=
If (Char.IsNumber(e.KeyChar)) Then
e.Handled = False
ElseIf (Char.ToUpper(e.KeyChar) >= "A"c And Char.ToUpper(e.KeyChar) <=
"F"c) Then
e.Handled = False
ElseIf (e.KeyChar = "<"c Or e.KeyChar = ">"c Or e.KeyChar = "?" Or
e.KeyChar = "="c) Then
e.Handled = False
Else
e.Handled = True
End If
End If
End If
End Sub

You will now notice, that apart from the number of characters accepted, we can also restrict the
type of input accepted by the textbox. Alpha textbox accepts only letters, Numbers textbox only
digits while Mixed accepts letters from A-F, <, >, ? , = characters only.
NB: You can handle events from many different sources with one delegate. The Sender object is
used to find out which control sent the event. Setting the Handled property of the
KeyPressEventArgs object to true tells .NET not to bother with this key press. In essence, it
throws it away.
Apart from ComboBox and TextBox controls, other data entry controls have properties that can
be used. For example,
The Button Control – is used to calling, cancelling or completing a process. It can be used for
data entry uses such as:
 You can put a picture on a Button and use it as a way to let the user jump to another data
screen.
 You can use a Button as an intermediate acceptance device. If the user clicks the Button,
some fields may become disabled or enabled depending on the value in another field.
 Often you have very complicated validation rules that preclude on-the-fly validation. You
can use a Button to start the validation process.
CheckBox control
 You can use this control in a list to allow the user to choose values within that list.
CheckBoxes are not mutually exclusive within the same parent control.
 You can also use a CheckBox to indicate a binary property. Such a property would be
true/false, yes/no, default/unique, and so on. Using a CheckBox in this manner allows
you to use a single control for two states of a property. This is not the case for the
RadioButton, however.
The RadioButton Control
This control is very similar to a CheckBox in that it provides a visual cue to the user as to just
what he or she has chosen. The similarities end there, though. The RadioButton is a mutually
exclusive device within the same parent control. The RadioButtons that are outside the
GroupBox are mutually exclusive with each other but not with those contained in the GroupBox.
The same is true for the RadioButtons within the GroupBox. RadioButtons should always come
in multiples. This is because clicking a RadioButton always sets its value to true. You can never
turn it off by clicking it again. The only way to do this is to choose another RadioButton.
Although you can use two RadioButtons to indicate a binary choice, this is a waste of a control.
You are better off using a CheckBox.
The DateTimePicker and MonthCalendar Controls
These two controls go hand in hand. Many times you will need to ask for a date from a user. The
MonthCalendar control is actually pretty cool. You can change its look to suit your needs, and
you can personalize it to display certain dates in bold. The main reason for using the
MonthCalendar is to allow the user to visually select a date or range of dates. Of course,
selecting a range of dates can be somewhat problematic because it requires quite a bit more
validation. For those times when you need the user to select only a single date, the
DateTimePicker is a better choice.

You can configure the DateTimePicker to show either time or date, or some custom format. If
you configure it as a date control, you can have a drop-down calendar appear for the user to
select from. If you configure it as a time control, you can have the user click an integrated spin
button to choose the time. Of course, the user can also type in the date or time if he or she wants.

ERROR HANDLING
No matter how good a programmer you are, you will need to provide some means of handling
errors that occur. Here are some main sources of errors:
 Coding bugs
 Inability to open files
 Wrong user input
 Unexpected data
Errors can be communicated and handled using
 ErrorProviders
 Error Dialog Box
i). ErrorProviders
The basic method of handling errors when entering data is the ErrorProvider object. Basically,
the ErrorProvider is a small icon that you can associate with any visible control on your form.
All you need to do is instantiate a new version of it and tell it which control to sit next to. The
user sees a small blinking icon next to the offending field. When the mouse hovers over the icon,
a ToolTip text message appears with some relevant information.
If you want, or need, to stave off validation until a whole form's worth of fields are entered, then
you could use this control to flag several fields that may be in error. This is validation at the end
of data entry. When you have a form whose fields are validated at the end of the data entry
phase, this is usually because many fields on the form are interrelated or maybe some fields are
required to be filled in. Each field cannot be validated on its own, but the form must be validated
as a whole.
Example, Create the following form with the following controls as follows:
 Add a Label whose text reads Name.
 Add a TextBox called txtName below this Label.
 Add a Label whose text reads Address.
 Add a TextBox called txtAddr below this Label.
 Add a Label whose text reads Favorite movie.
 Add a CheckedListBox called lstMovies below this Label.
 Add a Button called cmdSave whose text reads Save.
Add ErrorProvider object to your form and naming it Err, adds the following properties to each
control.
 Error on Err
 IconAlignment on Err
 IconPadding on Err
Add the following code
Public Class Form1

Private Sub cmdSave_Click(sender As Object, e As EventArgs) Handles cmdSave.Click


If (txtName.Text = String.Empty) Then
Err.SetError(txtName, "Cannot save form without a name")
Else
Err.SetError(txtName, "")
End If
If (txtAddr.Text = String.Empty) Then
Err.SetError(txtAddr, "Cannot save form without an address")
Else
Err.SetError(txtAddr, "")
End If
If (lstMovies.SelectedIndices.Count = 0) Then
Err.SetError(lstMovies, "Cannot save form without a favorite movie")
Else
Err.SetError(lstMovies, "")
End If
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load


lstMovies.Items.Add("Dumbo")
lstMovies.Items.Add("WindTalkers")
lstMovies.Items.Add("Paper Chase")
lstMovies.Items.Add("War Of The Worlds")
lstMovies.Items.Add("LOTR")
End Sub
End Class
If the program is executed, and Save button clicked without feeding data to any controls, the
following screen is displayed.
Hovering mouse on the error icon, relevant error messages are displayed stating the cause of
error.
ii). Error Dialog Box
Consider an error message like the one shown below.

Such error messages are obtuse errors that just disappear when Ok is clicked without indicating
the cause of error or even how to handle it. This is not too friendly.
When creating error messages, put the following considerations in mind:
 The error message should provide a good description of the error.
 The error message should suggest a way for the user to fix the problem.
 The error message should provide a way for your program to get around the error or
gracefully exit if the error is a showstopper.
Consider the example below with a better way to display an error with gentle prodding.
Create a form as the one shown below, as follows:
 Add a Label that reads Start Time.
 Add a TextBox called txtStart.
 Add a Label that reads End Time.
 Add a TextBox called txtEnd.
 Add a Label called lblTicks. Make its BorderStyle FixedSingle and center the text.
 Add a Timer to the form.
 Add a Button called cmdOK. It should read OK.

Add the following code


Public Class Form1
Public Sub New()

' This call is required by the designer.


InitializeComponent()

' Add any initialization after the InitializeComponent() call.


Timer1.Interval = 1000
Timer1.Start()
AddHandler cmdOK.Click, AddressOf Me.Ok_Click
txtStart.Text = DateTime.Now.ToShortTimeString()
txtEnd.Text = DateTime.Now.AddMinutes(-1).ToShortTimeString()
End Sub
Private Sub OK_Click(ByVal Sender As Object, ByVal e As EventArgs)
Dim Retval As DialogResult
Dim msg As String
msg = "The end time field has an incorrect value." & vbNewLine
msg += "The end time must be later than the start time" & vbNewLine
msg += "Press 'Yes' to automatically adjust the end time"
Retval = MsgBox(msg, 3, MsgBoxStyle.YesNo)
If (Retval = DialogResult.Yes) Then
txtEnd.Text = CDate(txtStart.Text).AddMinutes(1).ToShortTimeString()
txtEnd.SelectAll()
txtEnd.Focus()
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
lblTicks.Text = ((lblTicks.Text) & 1).ToString()
End Sub
End class
When the program is run, the Start Time is filled with the current time but the End time is filled
with current time -1 minute. When the OK button is clicked, the following error box is displayed.

This error dialog box tells the user explicitly what is wrong and what needs to be done to correct
the problem. In this case, the program is able to automatically correct the problem for the user
and offers to do so.
If the user clicks Yes, the end time will change to the start time plus 1 minute, the End Time
TextBox will be highlighted, and the text inside will be selected. If the user clicks No, the same
thing will happen, except the time will not be adjusted.
The user has been led back to the offending field and the field is ready to be edited. You should
show users errors like this whenever possible.

You might also like