Click here to Skip to main content
15,914,289 members
Articles / Programming Languages / Visual Basic
Article

A Self-validating Textbox

Rate me:
Please Sign up or sign in to vote.
2.85/5 (8 votes)
7 Aug 2007CPOL7 min read 91.2K   2.9K   63   22
An article on a textbox that validates input on keypress

Screenshot - Validating1.jpg

Introduction

Often, it is necessary to control the input of a textbox to maintain the successful functioning of an application, particularly those involving accounting and databases. This textbox controls what the user can type into it. It does this by validating the input character on KeyPress. It has nine modes that are all useful in different situations and can be changed via the ValidationFormat property in design or runtime.

As opposed to other validating textboxes, this is all done on KeyPress. So, there is no possible way that the user can input the wrong data. Although it has elements similar to the masked textbox, it provides functionality for alphanumeric, decimal, currency and, uniquely, capitalisation. Capitalisation is useful for when the user inputs their name into your fields. This way, when this information is stored, it is in the correct format in case the use has been forgotten.

Note: This was made in Visual Studio 2005 on Windows XP using .NET Framework 2.0.

Features

9 ValidationFormat Modes

  • None: Allows any characters.
  • Alphabetical: Allows only letters.
  • Numeric: Allows only numbers.
  • Alphanumeric: Allows only letters and numbers.
  • Decimal: Allows numbers and one decimal point. Accommodates for locality and difference in currency symbols and separator characters.
  • CapitaliseEachWordAlphabetical: Allows only letters and capitalises the first letter of each word.
  • CapitaliseEachWordAlphanumeric: Allows only letters and numbers and capitalises the first letter of each word.
  • CapitaliseEachWordAll: Allows any characters and capitalises the first letter of each word.
  • Currency: Allows only numbers, one currency symbol, one decimal separator and unlimited group separators. Accommodates for locality and difference in currency symbols and separator characters.
  • UpperCaseAlphabetical: Allows only upper case letters; letters typed in lower case will be converted to upper case.
  • UpperCaseAlphabetical: Allows only upper case letters and numbers; letters typed in lower case will be converted to upper case.
  • LowerCaseAlphabetical: Allows only lower case letters; letters typed in upper case will be converted to lower case.
  • LowerCaseAlphabetical: Allows only lower case letters and numbers; letters typed in upper case will be converted to lower case.

Validation on KeyPress, Leave and TextChanged

The validation of this control is done in 3 phases. The first is on the KeyPress event. If the user types a key that is not allowed by ValidationFormat, the key is simply rejected. The second phase of validation occurs on the Leave event. When the textbox loses focus, it checks that the contents of the textbox are correct in the unlikely event of the introduction of unwanted characters. In the third phase, the control validates on the TextChanged event. This final phase is enacted in the event that the user performs a paste in the textbox.

New Properties

This text box has five new properties compared to the standard textbox and all have a separate role in the validation. The first new property is, of course, the ValidationFormat property. This allows the designer to select what format they want their textbox in, whether it be Numeric, Alphabetical or any of the other modes.

The second new property is the ValidInput property. At OnLeave or TextChanged validation, if some form of invalid data is entered into the textbox, the InvalidInput property is set to false. This lets the designer know when there is invalid data.

The third new property is the AllowNull property. If this is set to false, then if the textbox is empty or becomes empty, the ValidInput property is set to false. This lets the designer know when there is a problem with the data.

The fourth new property is the DisplayTickOnValid property. As opposed to the normal error displaying an icon only when the user gets it wrong, this textbox displays an icon when the user gets it right as well, but only if you want it to.

The fifth new property is the ErrorMessage property, which will be discussed in the next section.

Everyone Knows When There's a Problem

I felt that one important thing when designing this was having not only the designer know when the textbox throws an error, but also letting the user know. To allow this, I added ErrorProvider to the textbox. When there is a problem with validation, ErrorProvider is set to display with an attached error, i.e. the tooltip that shows up over the error icon. The textbox then sets its ValidInput property to false, letting the designer know that there is a problem. It also sets its ErrorMessage property to match the error associated with ErrorProvider. There are 3 benefits to doing all of this:

  1. The user knows when there is a problem, allowing the user to correct it.
  2. The textbox indicates when there is a problem, allowing features in the program to take the correct action such as disabling a save button, etc.
  3. The program can access the associated error and display it to the user, letting the user know what is wrong.

Events

Associated with each of the new properties is a new event. Each new property has an associated PropertyChanged event. This is useful because designers can incorporate code that can:

  1. Allow them to take action when there is an error.
  2. Allow properties to be changed at runtime and have available reactions to those changes.
  3. Display, to the user, an error message when ErrorMessage is changed.

Using the Code

The code is simple, mostly. It is just a matter of compiling the control into a DLL and adding that to your toolbox. Then you can use it in any application you want. Here's how to add it to your toolbox:

  1. Compile the control.
  2. Right click the Toolbox -> Choose Items -> Browse for the DLL -> Add it and Apply -> Use the control.

The most useful part about this control, however, is the new ValidInput property I have added. When the textbox loses focus, it verifies that its content is valid by running a check against its current ValidationFormat. If the check returns a value specifying that the input is not valid, the ValidInput property is set to False. When the user goes to continue or commit the data, your program can check the textboxes. It sees if they are all valid and allows or disallows continuation. In addition to this, the control includes an in-built ErrorProvider that will show the user that their input is invalid, giving them a chance to change it.

The Code (or Parts of It)

Declarations Regarding Globalization

VB
Imports System.Globalization.NumberFormatInfo
Dim DSep As String = 
    CurrentInfo.NumberDecimalSeparator 
    ' finds decimal separator for local region
Dim GSep As String = 
    CurrentInfo.NumberGroupSeparator 
    ' finds group separator for local region
Dim CSym As String = 
    CurrentInfo.CurrencySymbol 
    ' finds currency symbol for local region

Alphabetical

VB
If Char.IsLetter(e.Keychar) = False Then
    e.Handled = True
End If

Numeric

VB
If Char.IsNumber(e.Keychar) = False Then
    e.Handled = True
End If

Alphanumeric

VB
If Char.IsLetterorDigit(e.Keychar) = False Then
    e.Handled = True
End If

Decimal

VB
If Char.IsNumber(e.KeyChar) = False Then
    If e.KeyChar = CChar(DSep) Then
        If Me.Text.Contains(DSep) Then '
            e.Handled = True           ' Allows only one decimal separator
        End If                         '
    Else
        e.Handled = True
    End If
End If

Checking Allow Null and Acting Appropriately

This is if the text property of the textbox is null.

VB
If Me.AllowNull = True Then
    Valid()
Else
    Me.InvalidErrorProvider.SetError(Me, 
        "Invalid Input: This textbox must not be empty.")
    Invalid()
End If 

Private Sub Valid()
    Me.InvalidErrorProvider.Clear()
    Me.ErrorMessage = Nothing
    Me.ValidInput = True
End Sub

Private Sub Invalid()
    Me.ErrorMessage = Me.InvalidErrorProvider.GetError(Me)
    Me.ValidInput = False
End Sub

The rest of the code is far too long to post in one large block.

Points of Interest

Capitalising was the most difficult part to get right, as there are so many variables. If the user decides to backspace, it has to check if it needs to capitalise. Then it has to capitalise the first letter and check -- in some instances -- if it is even a letter. Co-ordinating all these was a bit tricky and is probably a bit messy, so feel free to tidy up the code. An interesting thing I found was that with backspace and space, there has to be an exception for the backspace and space characters because they are blocked along with special characters.

One important thing that I had to focus on, which I hadn't originally considered, was managing the currency field. In particular, I needed to consider what and how money values were entered. Because different countries use different formats for their currency, it was necessary to tap into the System.Globalization namespace and work with the different elements it provided for allowing international compatibility. These included CurrentInfo.NumberDecimalSeparator, CurrentInfo.NumberGroupSeparator and CurrentInfo.CurrencySymbol.

History

  • July 3, 2007 -- Original version posted
  • July 6, 2007 -- Article updated
  • July 9, 2007 -- Article updated
  • August 7, 2007 -- Article and download updated

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Australia Australia
I am a Hobby programmer who works in the insurance industry as a broker. I also innovate within my role through building custom software to streamline processes.

Comments and Discussions

 
Generalnot able to work with it.. [modified] Pin
PrajaktPatil12-Aug-08 20:07
PrajaktPatil12-Aug-08 20:07 
hi I have the same problem which girish has..
what to do..?
Thanks And regards
Prajakt Patil

modified on Wednesday, August 13, 2008 2:29 AM

GeneralRe: not able to work with it.. Pin
The ANZAC12-Aug-08 23:24
The ANZAC12-Aug-08 23:24 
GeneralA very good idea !!!! THNX Pin
joaoalbertofn6-Jul-07 10:49
joaoalbertofn6-Jul-07 10:49 
GeneralRe: A very good idea !!!! THNX Pin
The ANZAC6-Jul-07 15:24
The ANZAC6-Jul-07 15:24 
AnswerRe: A very good idea !!!! THNX Pin
joaoalbertofn7-Jul-07 2:47
joaoalbertofn7-Jul-07 2:47 
GeneralRe: A very good idea !!!! THNX Pin
The ANZAC7-Jul-07 13:24
The ANZAC7-Jul-07 13:24 
GeneralRe: A very good idea !!!! THNX Pin
The ANZAC7-Jul-07 16:18
The ANZAC7-Jul-07 16:18 
GeneralRe: A very good idea !!!! THNX Pin
The ANZAC9-Jul-07 12:37
The ANZAC9-Jul-07 12:37 
GeneralRe: A very good idea !!!! THNX Pin
joaoalbertofn9-Jul-07 13:33
joaoalbertofn9-Jul-07 13:33 
GeneralSeveral flaws Pin
mav.northwind4-Jul-07 18:32
mav.northwind4-Jul-07 18:32 
GeneralRe: Several flaws Pin
The ANZAC4-Jul-07 20:15
The ANZAC4-Jul-07 20:15 
GeneralRe: Several flaws Pin
mav.northwind5-Jul-07 0:14
mav.northwind5-Jul-07 0:14 
GeneralRe: Several flaws Pin
The ANZAC5-Jul-07 1:28
The ANZAC5-Jul-07 1:28 
GeneralNot able to work with Pin
Girish4814-Jul-07 1:38
Girish4814-Jul-07 1:38 
GeneralRe: Not able to work with Pin
The ANZAC4-Jul-07 1:40
The ANZAC4-Jul-07 1:40 
GeneralRe: Not able to work with Pin
Girish4814-Jul-07 1:54
Girish4814-Jul-07 1:54 
GeneralRe: Not able to work with Pin
Girish4814-Jul-07 18:38
Girish4814-Jul-07 18:38 
GeneralRe: Not able to work with Pin
mav.northwind5-Jul-07 0:16
mav.northwind5-Jul-07 0:16 
GeneralDownload missing project Pin
mav.northwind3-Jul-07 10:19
mav.northwind3-Jul-07 10:19 
GeneralRe: Download missing project Pin
The ANZAC3-Jul-07 12:56
The ANZAC3-Jul-07 12:56 
GeneralRe: Download missing project Pin
mav.northwind3-Jul-07 18:54
mav.northwind3-Jul-07 18:54 
GeneralRe: Download missing project Pin
The ANZAC4-Jul-07 14:49
The ANZAC4-Jul-07 14:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.