How to allow only numbers in textbox?

mcerk

Regular
Joined
Nov 1, 2004
Messages
78
Hi. I'm triing to do my own textbox that would allow only numeric characters to be displayed (and it will allso allow . and ,).

So. I can prevent this characters to be pressed? how can I do it?
I wrote some code, but I don't think it will go this way.

thank you a lot

Visual Basic:
Private Sub myTextBox_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
        'if not pressed a key between 0 and 9 or , or .
        If Not (e.KeyValue >= 96 And e.KeyValue <= 105) Or e.KeyValue = 190 Or e.KeyValue = 188 Then
            'how can I erase pressed key? or is there better way of doing it?
        End If
End Sub
 
mcerk said:
Hi. I'm triing to do my own textbox that would allow only numeric characters to be displayed (and it will allso allow . and ,).

So. I can prevent this characters to be pressed? how can I do it?
I wrote some code, but I don't think it will go this way.

thank you a lot

Visual Basic:
Private Sub myTextBox_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
        'if not pressed a key between 0 and 9 or , or .
        If Not (e.KeyValue >= 96 And e.KeyValue <= 105) Or e.KeyValue = 190 Or e.KeyValue = 188 Then
            'how can I erase pressed key? or is there better way of doing it?
        End If
End Sub

hope the following can help you :D

Code:
Private Sub myTextBox_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles myTextBox.KeyDown
        If System.Text.RegularExpressions.Regex.IsMatch(CStr(e.KeyValue), "^[+-]?(\d*\.?\d+|\d+\.?\d*)([eE][+-]?\d+)?$") Then
            ........
        Else
            MsgBox("please enter digit")
        End If
    End Sub
 
Last edited:
I tried this, but this thing somehow doesn't work. The problem is, that when KeyDown event is triggered, the key (char) is allready displayed in textbox
 
mcerk said:
I tried this, but this thing somehow doesn't work. The problem is, that when KeyDown event is triggered, the key (char) is allready displayed in textbox

try the following

Code:
    Private Sub myTextBox_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles myTextBox.KeyDown
        If System.Text.RegularExpressions.Regex.IsMatch(CStr(e.KeyValue), "^[+-]?(\d*\.?\d+|\d+\.?\d*)([eE][+-]?\d+)?$") Then
            ........
        Else
            dim txt as string = myTextBox.text
            myTextBox.text=txt.substring(0,txt.length-1)
        End If
    End Sub
 
KeyPress event is the one you are looking for. And there is a much easier way to do that than RegEx I think :).

Code:
    Private Sub Text_KeyPress(args...)
    If Not Char.IsDigit(e.KeyChar) And Not Char.IsPunctuation(e.KeyChar)
         e.Handled = True 'tell the textbox not include the character
         MessageBox.Show("numbers and punctuation only please!")
    End If
    End Sub
Now, punctuation includes other signs too rather than only "." and "," so its up to you if you want to check like that or compare it otherwise.
 
mutant said:
KeyPress event is the one you are looking for. And there is a much easier way to do that than RegEx I think :).

Code:
    Private Sub Text_KeyPress(args...)
    If Not Char.IsDigit(e.KeyChar) And Not Char.IsPunctuation(e.KeyChar)
         e.Handled = True 'tell the textbox not include the character
         MessageBox.Show("numbers and punctuation only please!")
    End If
    End Sub
Now, punctuation includes other signs too rather than only "." and "," so its up to you if you want to check like that or compare it otherwise.


tx, this works perfectly
 
KeyPress has one very critical flaw that is almost always overlooked by junior programmers:

Are you going to disable pasting into the textbox? If not, then KeyPress won't work - you need to examine the textbox contents after every TextChanged event.
 
I See. but in TextChanged event I can not use:

e.Handled = True

So I solved pasting problem with some other procedure...


Do you have more elegant solution?
 
you can set the TextBox's style to accept only numbers being typed , but then you have to handle the pasting of text ( WM_PASTE ) , here's a quick example i knocked up for you ...
Visual Basic:
    Private Const ES_NUMBER As Int32 = &H2000I
    Private Const GWL_STYLE As Int32 = -16
    Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As IntPtr, ByVal nIndex As Int32) As Int32
    Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As IntPtr, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32

    Private numertext As NumericTextbox '/// this will handle WM_PASTE

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim style As Int32 = GetWindowLong(TextBox1.Handle, GWL_STYLE)
        style += ES_NUMBER
        SetWindowLong(TextBox1.Handle, GWL_STYLE, style)
        '/// now i subclass the textbox to handle the paste message / CTL + V
        numertext = New NumericTextbox(TextBox1.Handle)
    End Sub

Public Class NumericTextbox
    Inherits NativeWindow

    Private Const WM_PASTE As Int32 = &H302

    Public Sub New(ByVal handle As IntPtr)
        MyBase.AssignHandle(handle)
    End Sub

    Protected Overrides Sub WndProc(ByRef m As Message)
        If Not m.Msg = WM_PASTE Then
            MyBase.WndProc(m)
        ElseIf m.Msg = WM_PASTE Then
            '/// lets get the clipboard info that's being pasted
            If Clipboard.GetDataObject.GetDataPresent(DataFormats.Text) Then
                Dim s As String = DirectCast(Clipboard.GetDataObject.GetData(DataFormats.Text), String)
                If IsNumeric(s) Then '/// it's a numeric string being pasted
                    MyBase.WndProc(m)
                End If
            End If
        End If
    End Sub
End Class
hope it helps :)
 
Back
Top