1

I have an issue, The thing is I have to allow user to enter numeric value in text box up to one decimal point,

When all text selected and I try try to edit text by entering any numeric key, It wont let it change.

Here is the text box with value. Text Box with one decimal point value

The code behind, Keypress

Private Sub TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
    If Regex.IsMatch(TextBox1.Text, "\.\d") Then
        e.Handled = True
    End If
End Sub

Kindly anybody help or suggest better way.

I have added this code but I am unable to restrict user not to enter more then one decimal point value.

 If Not ((Asc(e.KeyChar) >= 48 And Asc(e.KeyChar) <= 57) Or Asc(e.KeyChar) = 46 Or Asc(e.KeyChar) = 8 Or Asc(e.KeyChar) = 127) Then
        e.KeyChar = ""
        e.Handled = False
    End If
DareDevil
  • 5,249
  • 6
  • 50
  • 88

2 Answers2

4

Try this: (not regex tho), but works great for numerics.

It allows for 1 x negative symbol, one fullstop (point), using backspace, and any numerics..

       Private Sub priceTextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles priceTextBox.KeyPress
       If IsNumeric(e.KeyChar.ToString) = False Then

            If e.KeyChar.ToString = "." And priceTextBox.Text.Contains(".") Then e.Handled = True
            If e.KeyChar.ToString = "-" And priceTextBox.Text.Contains("-") Then e.Handled = True

            If e.KeyChar.ToString <> "." Then
                If e.KeyChar <> ControlChars.Back Then
                    If e.KeyChar <> "-" Then
                        e.Handled = True
                    End If
                End If
            End If
        End If
        End Sub

EDIT

This allows for the above numerics, as well as only 1 decimal point. I kept it simple with more code lines to show steps, so you can see what actually happens. I am sure it can be improved, this is a quick and dirty version...

  • Allows for Globalization of the decimal character
  • Also catches a "paste" into the textbox, that normally circumvents the keypress catch routines

    Dim lastProperText As String = ""
    
    Private Sub priceTextBox_TextChanged(sender As Object, e As EventArgs) Handles priceTextBox.TextChanged
    
      If priceTextBox.Text = "" Then Exit Sub
      If IsNumeric(priceTextBox.Text) = False Then priceTextBox.Text = lastProperText
      If _containsDecimal(priceTextBox.Text, 2) = True Then priceTextBox.Text = lastProperText
    
    End Sub
    
    Private Sub priceTextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles priceTextBox.KeyPress
        Dim decimalSeparator As String = Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
    
        If IsNumeric(e.KeyChar.ToString) = False Then
    
            If e.KeyChar.ToString = decimalSeparator And priceTextBox.Text.Contains(decimalSeparator) Then e.Handled = True
            If e.KeyChar.ToString = "-" And priceTextBox.Text.Contains("-") Then e.Handled = True
    
            'allow backspace here
            If e.KeyChar = ControlChars.Back Then Exit Sub
    
            If e.KeyChar.ToString <> decimalSeparator Then
                If e.KeyChar <> ControlChars.Back Then
                    If e.KeyChar <> "-" Then
    
                        e.Handled = True
    
                    End If
                End If
            End If
        End If
    
        'BUG FIX
        If priceTextBox.SelectionStart > priceTextBox.Text.Length - 2 Then
          If _containsDecimal(priceTextBox.Text, 1) = True Then e.Handled = True
        End If
        '/BUG FIX
    
        'keep last good format.. we will use this in case something gets apsted in that does not meet our format...
        lastProperText = priceTextBox.Text
    
    End Sub
    
    Private Function _containsDecimal(stringtoCheck As String, decimalNumber As Integer) As Boolean
    
        Dim decimalSeparator As String = Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
    
        'check to allow only 1 decimal point
        Dim positionOfPoint As Integer = 0
    
        'get position of decimal point (.)
        positionOfPoint = InStr(stringtoCheck, decimalSeparator)
    
        'check if there are not characters after decimal point... 
        'if nothin after decimal point, allow this keypress, 
        'if there is already something after decimal point, escape this keypress
    
        'get length of string after "."
        Dim stringTail As String = ""
    
        If Not positionOfPoint = 0 Then
            stringTail = Mid(stringtoCheck, positionOfPoint)
            If stringTail.Length > decimalNumber Then
                Return True
            End If
        End If
    
    End Function
    
Louis van Tonder
  • 3,664
  • 3
  • 31
  • 62
  • :but it does not stops user to enter only one decimal point value. like I have shown in my image. – DareDevil Jul 16 '14 at 07:27
  • I have modified the code can you help me figure out how to Restrict up to one decimal point? Should I add TextChangedEvent? – DareDevil Jul 16 '14 at 08:02
  • 2
    You should note that this code doesn't support [globalization](http://msdn.microsoft.com/en-us/library/system.globalization(v=vs.110).aspx). It fails with my `nb-NO` culture as the decimal separator is `,` not `.`. Also, it doesn't prevent the user from pasting non-numeric text into the text box. – Bjørn-Roger Kringsjå Jul 16 '14 at 08:32
  • 1
    @Bjørn-RogerKringsjå , yeah, the culture will be an issue. As I said, it can be extended (should be really) It's merely a proof of concept. – Louis van Tonder Jul 16 '14 at 08:38
  • @Bjørn-RogerKringsjå, I updated the code to allow for cultureinfo. Please feel free to provide more suggestions for improvements. – Louis van Tonder Jul 16 '14 at 08:44
  • 1
    @LouisvanTonder Great! Your effort deserves a +1! – Bjørn-Roger Kringsjå Jul 16 '14 at 08:49
  • @Bjørn-RogerKringsjå and DareDevil . I have now updated this code to indeed catch string "pasted" in, that do not stick the the required format... what.. I was taking a break from work stuff :-) – Louis van Tonder Jul 16 '14 at 09:18
  • But Above code has bug in it, If i delete the left most non decimal value like if my TextBox = "8.3" and I want to edit the left most value , its not letting me do so. – DareDevil Jul 16 '14 at 09:46
  • Ahh ok, I can see that happening... here you will probably have to check cursor position in the textbox. – Louis van Tonder Jul 16 '14 at 09:48
  • ok, this is getting "dirtier" by the moment... bug fix applied... One shoudl probably wrap this up neatly in a custom class with all the bells and whistles. But code works as above... – Louis van Tonder Jul 16 '14 at 09:56
  • :) I will dig down , put more efforts to achieve it – DareDevil Jul 16 '14 at 10:09
  • Ok, but as above bug fix is applied... you CAN now edit your "8.3" – Louis van Tonder Jul 16 '14 at 10:10
2

I have tried this code:

Works Fine Now.. One Digit after decimal point, you may add \d\d to add digits in Regex

 Private Sub TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
    If TextBox1.SelectedText.Length = TextBox1.Text.Length Then
        TextBox1.Clear()
    End If
    If Char.IsDigit(e.KeyChar) = True OrElse Char.IsControl(e.KeyChar) = True OrElse e.KeyChar = "."c Then
        If Regex.IsMatch(TextBox1.Text, "\.\d") Then
            'This makes backspace working
            If e.KeyChar = CChar(ChrW(8)) Then
            Else
                e.Handled = True
            End If
        End If
    Else
        e.Handled = True
    End If

End Sub
DareDevil
  • 5,249
  • 6
  • 50
  • 88