1.11M Members

Money Only TextBox


I've been working on a Textbox that only accepts 0-9, Decimal Point, and the Backspace Keys. Also keeps it in the base form 0.00. Max value is 999999.99 can be set as needed. It works as expected, but I have to ask if I have remade the wheel. This sub is set as the KeyPress Event for the textboxes on the form and will not allow wrong KeyChar's to be entered. Any tips or criticisms welcome..

 ''' <summary>
    ''' Previews the Key stroke attempting to be entered into textbox
    ''' allows or disallows the key depending on the 
    ''' e.KeyChar, position, and Caret Position.
    ''' Only 0-9 a single decimal point and 2 places after the decimal.
    ''' The Backspace key is also allowed
    ''' Max Value = 999999.99
    ''' </summary>
    ''' <param name="sender">TextBox</param>
    ''' <param name="e"> Handled = true disallows Key :: Handled = False Allows Key
    ''' </param>
    ''' <remarks></remarks>
    Public Sub BoxKeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)

        'allow Backspace and exit the sub no need to process further
        If e.KeyChar = Chr(8) Then e.Handled = False : Exit Sub

        Dim tb As TextBox = DirectCast(sender, TextBox) 'Get the TextBox. 

        'Fill Physical variables
        'Decimal Point(if present) Location :: If not present (-1)
        Dim point As Integer = tb.Text.IndexOf(".")
        Dim caretIndex As Integer = tb.SelectionStart 'Caret position
        Dim len As Integer = tb.Text.Length 'Length of text present already in textbox

        'Check if a digit has been entered
        If Not Char.IsDigit(e.KeyChar) Then e.Handled = True

        'If the Key being entered is a Decimal Point and it will
        'be the First Character then allow it and exit the Sub.
        If e.KeyChar = "." And point = -1 Then e.Handled = False

        'if it wasn't handled above check further
        If Not e.Handled Then
            If point = -1 Then 'No Decimal Point has been entered : Allow digits
                e.Handled = False
            ElseIf (len - point) > 2 Then '2 Decimal Places are present : Disallow Digits
                e.Handled = True
            End If

            'if user moves caret to add keychar to within string
            If caretIndex < len Then
                If point > -1 And caretIndex <= point Then
                    e.Handled = False
                End If

                'If the character is a decimal make sure it wouldn't
                'create more than 2 decimal places. len - caretIndex > 2 
                If e.KeyChar = "." And (len - caretIndex) > 2 Then e.Handled = True
                If e.KeyChar <> "." And len - point = 1 Then e.Handled = False
                If e.KeyChar = "." And (len - caretIndex) = 2 And point = -1 Then e.Handled = False
            End If
        End If

        'Set Max Value to "999999.99"
            If len > 0 Then
                If e.Handled = False And CDbl(tb.Text.Insert(caretIndex, e.KeyChar.ToString)) <= 999999.99 Then
                    e.Handled = False
                    e.Handled = True : Exit Sub
                End If
            End If
        Catch ex As Exception
            e.Handled = True
        End Try

    End Sub

   ''' <summary>
    ''' Ensures the format of the entered currency value is correct
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Public Sub TextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim tb As TextBox = DirectCast(sender, TextBox)
        Dim txt As String = Trim(tb.Text)
        Dim len As Integer = txt.Length
        Dim decimalPresent As Boolean = txt.Contains(".")
        Dim decimalLoc As Integer = txt.IndexOf(".")

        'If no decimal present add it
        'and two 0's after
        If Not decimalPresent Then
            txt = txt & ".00"
        ElseIf decimalPresent And decimalLoc = len - 1 Then
            txt = txt & "00"
        End If

        'Reset Variables
        len = txt.Length
        decimalPresent = txt.Contains(".")
        decimalLoc = txt.IndexOf(".")

        'If value in .1 or 2.2 add last 0 
        If decimalPresent And (len - 2) = decimalLoc Then
            txt = txt & "0"
        End If

        'Reset Variables
        len = txt.Length
        decimalPresent = txt.Contains(".")
        decimalLoc = txt.IndexOf(".")

        'if value in the form .10 .12 .00 inset 0 before the decimal
        If decimalPresent And decimalLoc = 0 Then
            txt = "0" & txt
        End If

        tb.Text = txt

    End Sub

Have you read this about handling which chars can be entered in a TextBox?
And this about Masked TextBox?

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

'97 - 122 = Ascii codes for simple letters
'65 - 90  = Ascii codes for capital letters
'48 - 57  = Ascii codes for numbers

If Asc(e.KeyChar) <> 8 Then
    If Asc(e.KeyChar) < 48 Or Asc(e.KeyChar) > 57 Then
        e.Handled = True
    End If
End If


Public Function OnlyDigitsOnKeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)


    If System.Char.IsDigit(e.KeyChar) = False And e.KeyChar <> Microsoft.VisualBasic.Chr(8)        And e.KeyChar <> Microsoft.VisualBasic.Chr(46) Or (InStr(sender.text, ".") > 0 And  e.KeyChar = Microsoft.VisualBasic.Chr(46)) then
        e.Handled = True
    End If
    Catch ex As Exception
    End Try
End Function

YOU CAN GO TO [HERE], (Microsoft Link)


Having One more Solution for you.
Not only With Numbers but with others too

Create a new module: Remove all the things.
Now add this code:

Imports System.Text.RegularExpressions
Module Module1
Public Enum ValidationType
    Only_Numbers = 1
    Only_Characters = 2
    Not_Null = 3
    Only_Email = 4
End Enum
Public Sub AssignValidation(ByRef CTRL As Windows.Forms.TextBox, ByVal Validation_Type As ValidationType)
    Dim txt As Windows.Forms.TextBox = CTRL
    Select Case Validation_Type
        Case ValidationType.Only_Numbers
            AddHandler txt.KeyPress, AddressOf number_Leave
        Case ValidationType.Only_Characters
            AddHandler txt.KeyPress, AddressOf OCHAR_Leave
        Case ValidationType.Not_Null
            AddHandler txt.Leave, AddressOf NotNull_Leave
        Case ValidationType.Only_Email
            AddHandler txt.Leave, AddressOf Email_Leave
    End Select
End Sub
Public Sub number_Leave(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
    Dim numbers As Windows.Forms.TextBox = sender
    If InStr("1234567890.", e.KeyChar) = 0 And Asc(e.KeyChar) <> 8 Or (e.KeyChar = "." And InStr(numbers.Text, ".") > 0) Then
            e.KeyChar = Chr(0)
            e.Handled = True
        End If
    End Sub
    Public Sub OCHAR_Leave(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        If InStr("1234567890!@#$%^&*()_+=-", e.KeyChar) > 0 Then
            e.KeyChar = Chr(0)
            e.Handled = True
        End If
    End Sub
    Public Sub NotNull_Leave(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim No As Windows.Forms.TextBox = sender
        If No.Text.Trim = "" Then
            MsgBox("This field Must be filled!")
        End If
    End Sub
    Public Sub Email_Leave(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim Email As Windows.Forms.TextBox = sender
        If Email.Text <> "" Then
            Dim rex As Match = Regex.Match(Trim(Email.Text), "^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,3})$", RegexOptions.IgnoreCase)
            If rex.Success = False Then
                MessageBox.Show("Please Enter a valid Email Address", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Email.BackColor = Color.Red
                Exit Sub
                Email.BackColor = Color.White
            End If
        End If
    End Sub
End Module

GO TO FORM and ADD the code respectively to Form1.Load event:

' Add this For only Numbers.
    AssignValidation(Me.TextBox1, ValidationType.Only_Numbers)
' Add this For only characters.
    AssignValidation(Me.TextBox1, ValidationType.Only_Characters)
' Add this For only is not empty.
    AssignValidation(Me.TextBox1, ValidationType.Not_Null)
' Add this For only email.
    AssignValidation(Me.TextBox1, ValidationType.Only_Email)

What changes you might have to do?
If you are having the Textbox1 for only numbers.
then code will include textbox1 else whatever your textbox name:
For example: your textbox name: TB1 then

    AssignValidation(Me.TB1, ValidationType.Only_Numbers)

If you are confused then tell me, I will create Tutorial/source file for you


Here's a rather simple way to validate the text from a textbox:

Dim strtoint As Double = 0
'Check for valid number
If Double.TryParse(TextBox1.Text, strtoint) Then
    'Less than 1 add leading 0
    If strtoint < 1 Then
        TextBox1.Text = "0" + TextBox1.Text
    'A whole number? add trailing 0's and a decimal
    ElseIf strtoint = Math.Truncate(strtoint) Then
        TextBox1.Text += ".00"
    'Only 1 decimal place? add trailing 0
    ElseIf strtoint * 10 = Math.Truncate(strtoint * 10) Then
        TextBox1.Text += "0"            
    End If        
    MessageBox.Show("Invalid Input")
End If

This can easily work in which ever handler you want to use

Question Answered as of 6 Months Ago by Deep Modi, ddanbe and tinstaafl

Thank You all for your quality responses. I really appreciate the input.

I see from the varying code samples this objective can be skinned in a lot of different way. Again Thank You All!!

Isn't it about time forums rewarded their contributors?

Earn rewards points for helping others. Gain kudos. Cash out. Get better answers yourself.

It's as simple as contributing editorial or replying to discussions labeled or OP Kudos

This question has already been solved: Start a new discussion instead
Start New Discussion
Tags Related to this Article