TextBox - Only allow Numeric and ONE full stop (representing a decimal number) VB.NET

15,540

Solution 1

The Asc function is an old VB6 function which should be avoided when writing new .NET code. In this case, you could compare the character to see if it is in a certain range, like this:

If e.KeyChar <> ControlChars.Back Then
    If (e.KeyChar < "0"c) Or (e.KeyChar > "9"c) Then
        e.Handled = True
    End If
End If

However, I would suggest simply listing the valid characters, like this:

e.Handled = ("0123456789.".IndexOf(e.KeyChar) = -1)

As far as checking for multiple decimal points, you could do something in the key press event, like this:

If e.KeyChar = "."c Then
    e.Handled = (CType(sender, TextBox).Text.IndexOf("."c) <> -1)
ElseIf e.KeyChar <> ControlChars.Back Then
    e.Handled = ("0123456789".IndexOf(e.KeyChar) = -1)
End If

However, while it's nice to have the ability to filter out invalid key strokes, there are many problems with doing so. For instance, even with all of that checking, the following entries would all still be allowed, even though they, likely, should all be invalid:

  • 12.
  • 0000
  • 0001.

The other big problem is that your code will be culture dependent. For instance, in Europe, often a comma is used as the decimal point. For these reasons, I would recommend, if possible, simply using Decimal.TryParse in the Validating event, like this:

Private Sub TextBox1_Validating(sender As Object, e As CancelEventArgs) Handles TextBox1.Validating
    Dim control As TextBox = CType(sender, TextBox)
    Dim result As Decimal = 0
    Decimal.TryParse(control.Text, result)
    control.Text = result.ToString()
End Sub

Solution 2

Parse the string (text of the TextBox or whatever) to see whether it already contains a decimal point. Dont handle the keypress if thats the case:

VB.NET:

Private Sub TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
    Dim FullStop As Char
    FullStop = "."

    ' if the '.' key was pressed see if there already is a '.' in the string
    ' if so, dont handle the keypress
    If e.KeyChar = FullStop And TextBox1.Text.IndexOf(FullStop) <> -1 Then
        e.Handled = True
        Return
    End If

    ' If the key aint a digit
    If Not Char.IsDigit(e.KeyChar) Then
        ' verify whether special keys were pressed
        ' (i.e. all allowed non digit keys - in this example
        ' only space and the '.' are validated)
        If (e.KeyChar <> FullStop) And
           (e.KeyChar <> Convert.ToChar(Keys.Back)) Then
            ' if its a non-allowed key, dont handle the keypress
            e.Handled = True
            Return
        End If
    End If

End Sub

C#:

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if ((e.KeyChar == '.') && (((TextBox)sender).Text.IndexOf('.') > -1))
    {
        e.Handled = true;
        return;
    }

    if (!Char.IsDigit(e.KeyChar))
    {
        if ((e.KeyChar != '.') &&
            (e.KeyChar != Convert.ToChar(Keys.Back)))
        {
            e.Handled = true;
            return;
        }
    }
}

Solution 3

How about using Regex?

This will validate a decimal number or whole number:

VB

If New Regex("^[\-]?\d+([\.]?\d+)?$").IsMatch(testString) Then
    'valid
End If

C#

if (new Regex(@"^[\-]?\d+([\.]?\d+)?$").IsMatch(testString))
{
    //valid
}
Share:
15,540
user1662306
Author by

user1662306

Updated on July 12, 2022

Comments

  • user1662306
    user1662306 almost 2 years

    I have the following code, and am looking to add in the fact it can allow only one decimal point (full stop) to be added anywhere within the string.

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

    It will work by only accepting numeric numbers, so how can I incorporate ONE decimal point in this piece of code?

    Thanks