Search code examples
regexvb.nettextboxkeypressnumeric

TextBox not editing after SelectAll in vb.net


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

Solution

  • 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