XTab's Blog

Ged Mead's Blog at vbCity

vbCity Blogs moved to:
http://cs.vbcity.com/blogs
  Home :: Syndication  :: Login

JanFebruary 2010Mar
SMTWTFS
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213

Archives

Topics

Ramblings

VB.NET

  This is a question that seems to come up a lot in the forums:- How can I restrict the TextBox input to numerals, or only a single occurrence of a decimal point, or some other restriction?

  As ever, there are several approaches. If the restriction is something basic, such as numerals only then the easy approach is to use the KeyPress event. What you can do is stop the character from appearing in the TextBox, test to see if it is allowable and, if it is, then allow it to continue.

Letters Only
   To take an example which only allows letters of the alphabet, it would look like this:

    Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress

        e.Handled = True

 

        If e.KeyChar Like "[A-z]" Then e.Handled = False

 

    End Sub

  In this snippet, it is the e.Handled = True which blocks the input temporarily. The next line assesses whether the key press is a letter of the alphabet*, either lower or upper case, and if it is then the handled setting is reversed. This allows the key press to be passed to the TextBox display. If it fails the test, the block on this key press remains.

  * Depending on your locale and keyboard, some other keys are allowed. These include symbols that are used in combination with characters in some languages, such as accents. In most cases this is the behaviour you will want.

Specific Keys
Sometimes you may want to allow certain keys. A common situation is where you will let the user use the Backspace to correct an error when inputting:

    Private Sub TextBox2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox2.KeyPress

        e.Handled = True

 

        If e.KeyChar Like "[A-z]" _

        Or e.KeyChar = Chr(&H8) Then

            e.Handled = False

        End If

 

    End Sub

  In this case, it is the Chr(&H8) which identifies and allows the Backspace.

Numbers Only
  Another common requirement is to restrict input to numerals. Of the several possible approaches, using IsNumeric is one of the most straightforward:

    Private Sub TextBox3_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox3.KeyPress

        e.Handled = True

        If IsNumeric(e.KeyChar) Then e.Handled = False

    End Sub

  Sometimes that is too restrictive though. What happens if you want to allow the user to enter decimal points or (depending on their locale) commas to break up large numbers? Allowing these individual characters is simple, but there is another potential catch as we will see in a moment:

    Private Sub TextBox4_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox4.KeyPress

        e.Handled = True

        If IsNumeric(e.KeyChar) _

        Or e.KeyChar = "." _

        Or e.KeyChar = "," Then

            e.Handled = False

        End If

    End Sub

Only One Decimal Point
  In most cases where users are inputting numeric values you will want to restrict them to a single decimal point. The code above will allow multiple entries. Again, there are several solutions, but the following one will usually do the job:

    Private Sub TextBox5_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox5.KeyPress

        e.Handled = True

        If e.KeyChar <> "." Then

            If IsNumeric(e.KeyChar) Then e.Handled = False '

        ElseIf TextBox5.Text.Contains(".") Then

            MessageBox.Show("Only one decimal point allowed")

        Else

            e.Handled = False

        End If

    End Sub

Command Keys
   If you use any of the previous methods, you will be able to control the standard input keys. But there is another group of keys - Command keys - which won't be excluded by the use of the e.Handled approach. These include such keys as Home, End, Tab, and so on. You may risk alienating your users by excluding these, but there may be times when it is reasonable to do so, in which case you'll need to know how.

  A good way is to intercept the message at the window level and you can do this by overriding the ProcessCmdKey function. Here's how:

  Create a new class which inherits from the basic TextBox. Override the ProcessCmdKey function and test for the currently pressed key in a similar way to that used in the earlier examples. If the key is one you want to suppress then you return True and the Windows message pump will ignore it.

  The following code will be all you need:

Public Class CustomTextBox

 

    Inherits System.Windows.Forms.TextBox

 

    Sub New()

        Me.BackColor = Color.Azure

    End Sub

 

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean

 

        ' Declare a variable of type Keys enumeration

        ' named keyPressed.

        ' Cast the msg's WParam as a KeyEnum value

        ' and assign it to the keyPressed variable.

 

        Dim keyPressed As Keys = CType(msg.WParam.ToInt32(), Keys)

 

        ' Process the key that is pressed.

        '  If keyPressed = Keys.Home Or keyPressed = Keys.End Then Return True

        If keyPressed = Keys.Tab Then Return True

 

        ' Return the Command key message

        Return MyBase.ProcessCmdKey(msg, keyData)

 

    End Function

 

End Class

  The light blue back color is simply to make this sub-classed TextBox look slightly different from the default one for demo purposes, but of course is not a key part of the key checking functionality. As you can see, my example blocks the Tab key. You can add or replace other keys, such as Home and End.

Multiple Options
  Handling the KeyPress is fine if you only have a few TextBoxes for which you are controlling input. If there are going to be a lot of them throughout your application, or if you have different input rules for several TextBoxes, then again it may be worth your while to create your own inherited version.

  The following example deals with some of the previous scenarios, but allows the input rule to be selected from an enumeration of choices. The choices used here remain basic, but of course you can expand this idea much further.

  Here is the code:

Public Class RestrictedTextBox

    Inherits System.Windows.Forms.TextBox

 

    Enum RestrictionCategory

 

        NoRestriction

        NumeralsOnly

        LettersOnly

        AlphanumericOnly

 

    End Enum

 

    Private _allowedKeys As RestrictionCategory

 

 

    Property AllowedKeys() As RestrictionCategory

 

        Get

            Return _allowedKeys

        End Get

 

        Set(ByVal Value As RestrictionCategory)

            Select Case Value

                Case 1 To 3 ' One of the enum choices

                    _allowedKeys = Value

                Case Else ' No restriction

                    _allowedKeys = 0

            End Select

 

        End Set

 

    End Property

 

 

    Protected Overrides Sub OnKeyPress(ByVal e As KeyPressEventArgs)

 

        MyBase.OnKeyPress(e)

 

        '  Test whether key is allowed, based on the current choice

        '  from the enum

 

        Select Case _allowedKeys

 

            Case 1 'Numerals only

 

                If IsNumeric(e.KeyChar) Then

                    Exit Sub

                Else

                    e.Handled = True

                End If

 

            Case' Letters Only

 

                If e.KeyChar Like "[A-z]" Then

                    Exit Sub

                Else

                    e.Handled = True

                End If

 

            Case' Alphanumeric

                If e.KeyChar Like "[A-z]" _

                Or IsNumeric(e.KeyChar) Then

                    Exit Sub

                Else

                    e.Handled = True

                End If

 

        End Select

 

    End Sub

 

End Class

  The key areas are the enumeration which is called RestrictionCategory. These are automatically assigned values from 0 to 3. The Property AllowedKeys and its backing Field carry out the standard roles of a Property, the user being able to set the AllowedKeys property in code. (You could improve this by having the property appear in the Properties Window).

  The core of this class is the overridden OnKeyPress method. This checks for the chosen enumeration and then either allows or applies the blocking filter to the currently pressed key. This works in a very similar way to the individual KeyPress approach used in the earlier examples.

  By default, all keys will be allowed and to set the enumeration of your choice, you simply include code similar to the following somewhere appropriate in your form (I've used the Form Load event for my example):

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Me.RestrictedTextBox1.AllowedKeys = RestrictedTextBox.RestrictionCategory.NumeralsOnly

 

    End Sub

Summary
  I think that a combination or extension of any of the above approaches will enable you to control exactly what you will allow the user to input into a TextBox.

posted on Tuesday, June 09, 2009 9:28 AM

Feedback

# re: Restricting TextBox Input 11/2/2009 9:40 AM Prince Chacko
How can i restrict to 6 charcter after 6 character give a beep sound

Post Feedback

Title:
Name:
Url:
Comments: 
Protected by Clearscreen.SharpHIPEnter the code you see: