Archive for February, 2009

Textbox Validation

February 22, 2009

TEXTBOX VALIDATION

 
Inbuilt (and transparent) validation of data entry with user controls can be a usefull filter for a UI.  Typically there will be a string parser or Regular Expressions will be used.  I have often found it frustrating that .NET Windows Forms controls -especially the Textbox- don’t have simple validation.    OK, there is the Mask Textbox but this is listed to some specific data types.
 
You should add it. 
 

ABOUT

 
There are a number of HowTo articles including in Visual Studio Help;

Adding Regular Expression Validation

A Windows Forms Control Development Sample

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEV.v10.en/dnwinforms/html/custcntrlsamp1.htm

I have taken this and developed a custom validated textbox and have come across some issues.

  1. If dynamic validation is used, that is, the validation occurs as text is typed, typically, initial characters that are entered are invalid until the string reaches a certain point.
    eg a Data DD/MM/YYYY   will be invalid at least until 10 characters are entered.
  2. If the user input is trapped until a valid entry is completed then thsi can be a real pain.

    THE USER OFTEN WILL HAVE TO GUESS WHAT IS VALID !@#$%^&**&^%$#

    Have you ever been to one of those web sites that does this to you?  .. You normally kill the browser to escape!

  3. Simply allowing the user to "escape" at any point of data entry can cause programming issues.
    • Code that uses that value must therefore validate the entry before using it, which defeats the purpose of control based validation.
The main question is when to do the validation and when to enforce the validation:
  • The validator can be encapsulated in the control and available as a method to be called by code returning true or false… Take care with multi-threading though.
    It would be best to do this rather than embedded the validation in other code.
  • If dynamic validation is used, delay the onset of any enforcement to a suitable point.

There are actually two types of validation.:

  1. The main one is the overall validation check.  Is the string valid for the data type?
  2. The second one concerns the string as entered thus far:  For the data type lexicon (Railroad Diagram) is the string correctly follwing the lexicon?

Consider a DD/MM/YYYY date type.:  

  • 12/09/2001   is valid accordingto the first and second tests.
  • 12/09            is not a valid string but is correct so far

Whilst a value is being entered, the second test is what should be applied, with the first applying when users exits or when the value is accessed by external code.

A consequence of this is that a blank string won’t raise any alarm bells.

Another issue is that the control should restrict character entries to those which are part of the lexicon, and discard the others.
Question: What feedback to give the user for invalid keys.

Expression Validation

 Whilst I find Regular Expressions (RE) a bit difficult, as I only look them when I occassionally need them,
RE is THE technology for this purpose so it makes sense to use it.
 

ToDo: <Enter best Regular Expression Links here .. Comments invited>

Some validations are a little cumbersome though.  For example, its is easy enough to validate a data as DD/MM/YYYY  except that limiting DD to 1 to 31 and MM to 1 to 12 (or viz) is more difficult. 

It may be quick and dirty to just attempt the string to data type conversion in a TRY .. CATCH block
and return true only if catch is not entered.

My Validated Textbox Control

I constructed a validated textbox class inheriting from the System.Windows.Forms.Textbox class.  I placed this in a Windows Control Class Library project so that it can be referenced in other projects.  I added certain properties in a manner that allows them to be entered or selected from Visual Studio property page (F4) when used in a Form (VB Code easily translated into C#):

<System.ComponentModel.Category("Behavior")> _
Public Property RegularExpression() As String
    Get
        Return m_RegularExpression
    End Get
    Set(ByVal Value As String)
         m_RegularExpression = Value
        use_RegularExpression = Value
    End Set
End Property

RegularExpression then appears as a text entry on the control’s property page when it is used.

I also added a number of other properties to appear on the property page including:

  • ValidChar (String)
    • A string containing the valid characters to enter 
    • eg for Date "1234567890/" 
    • Not a Regular Expression though.
    • Whenever a key is pressed (KeyPressed handler) the key is discarded if not in the string.
  • DataType (ValidTypes) 
    • Provide some prebuilt validated types.
    • Create a list of type names as an enumerated type (ValidTypes) and use this as this property’s type. 
    • The enum names then appear for selection on the property page.
           
      ie. They appear as a dropdown list on the property page.
    • When this property is set, the Regular Expression and ValidChar properties are automatically set (and update on the property page) ..Wala
    • My default value is UInt
  • Dynamic Validation (Boolean)
    • If true then input is constantly validated and user is locked in until a valid string is entered
    • The default value is False
  • Escape key  (System.Windows.Forms.Keys
    • When Dynamic Validation is used it allows the user to "escape" when this key is pressed.
    • Appears as a dropdown list on the property page.
    • TrickThis is implemented by temporily setting the RegularExpression to "."   .. Anything goes!
      • Hence the use_RegularExpression   and m_RegularExpression   private values in the RegularExpression property
        • use_RegularExpression is what is used in the valiadtion.  m_RegularExpression is constant and used to restore use_RegularExpression
    • My default value is ESC

 User Feedback

Often BEEP is used as feedback when an invalid key is pressed or the string is invalid. I find this antagonising. 

A simple solution as part of the validation process is to use background coloring such as :

  • LightPink if the string is invalid
  • LightYellow if string is valid
  • Briefly bright red if invalid key is pressed

These apply regardless of whether Dynamic Validation is used or not.

ToDo: Add these as UI properties to be set.

OTHER UI Things:

  • I set a second special key property (configured via the property page) that when pressed clears the textbox.  Default is DEL
  • I make sure that  the left and right arrow keys as well as Home End etc. apply to moving about the string … There may be others needed.
    This is an issue because they will fail the ValidChars test.
  • If the string beomes valid, this is stored.  When the user "escapes"  the valid can be returned to this last valid value, or even cleared.

Summary

A validated textbox should behave in a manner that that doesn’t frustrate the user.  Above, I have presented some options for implementing a good UI whilst making the validation as transparent as possible.

In summary:

  • Create as a user control from textbox class.
  • Use Regular Expressions for Validation but don’t trap the user in the control.
  • Validate text characters and discard invalid ones.
  • Provide dynamic visual UI fedback as to the validity state. (Not BEEP)
  • Use "RailRoad Diagram" validation whilst a string is being entered to provide feeedback as to how the entry is progressing rather than overall final validation.
  • Apply the RegularExpression validation when the user attempts to exit the control or the Validate method is externally actioned.
  • For deeper/more complex validation, attempt the data conversion in a Try .. Catch block
  • Determine whether Dynamic enforcement is to apply.  If so have an escape key.
  • Implement properties so that they can be configued in Visual Studio
  • Implement some standard data types to be selected from property pages, that automatically enter ValidCharacters and the RegularExpression properties but still allow cusom entries
  • Make the textbox behave as much as possible like a normal textbox (but with validation applied)

Advertisements