Make KeyChar Accept Decimal

Andy 1 Reputation point
2021-10-30T17:42:08.813+00:00

Hi I am trying to build a custom calculator to make my data entry more efficient. I am trying to limit a textbox in Visual Basic to only accept one decimal point. So far this code only accepts integers and the Backspace button.

Dim Ch As Char = e.KeyChar
If Not Char.IsDigit(Ch) AndAlso Asc(Ch) <> 8 Then
e.Handled = True
End If

Any straightforward suggestions to limit this textbox to accept only 1 decimal point? Thank you.

VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,642 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Castorix31 82,751 Reputation points
    2021-10-31T01:12:53.757+00:00

    Any straightforward suggestions to limit this textbox to accept only 1 decimal point? Thank you.

    For that, you can do something like this (but you should also handle (or disable) copy/paste) :

    Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
        Dim sDecimalSeparator As String = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
        Dim sText As String = (CType(sender, TextBox)).Text
        Dim sKey As String = e.KeyChar.ToString()
        If Not ((Char.IsDigit(e.KeyChar) Or
            (sKey.Equals(sDecimalSeparator) And Not (sText.Contains(sDecimalSeparator))) Or
            e.KeyChar = vbBack Or
            (ModifierKeys And (Keys.Control Or Keys.Alt)) <> 0)) Then
            e.Handled = True
            Console.Beep(1000, 10)
        End If
    End Sub
    

  2. Karen Payne MVP 35,291 Reputation points
    2021-10-31T11:51:17.507+00:00

    The following is a custom TextBox which disallows more than one decimal from direct input and also from CTRL+V. To check if there is a value use HasValue, get as a decimal, AsDecimal.

    Add the control to your project, build the project and the control is now available in the IDE Toolbox.

    Imports System.Globalization
    
    Public Class NumericTextBox
        Inherits TextBox
    
        Private ReadOnly _decimalSeparator As Char =
            CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.Chars(0)
    
        Public Sub New()
            TextAlign = HorizontalAlignment.Right
        End Sub
    
        Protected Overrides Sub OnKeyPress(ByVal e As KeyPressEventArgs)
    
            If Not Char.IsControl(e.KeyChar) AndAlso Not Char.IsDigit(e.KeyChar) AndAlso e.KeyChar <> _decimalSeparator Then
                e.Handled = True
            End If
    
            If e.KeyChar = _decimalSeparator AndAlso Text.IndexOf(_decimalSeparator) > -1 Then
                e.Handled = True
            End If
    
            MyBase.OnKeyPress(e)
    
        End Sub
    
        Public Function HasValue() As Boolean
            Return Not String.IsNullOrWhiteSpace(Text)
        End Function
        Public Function AsDecimal() As Decimal
            Dim value As Decimal
            Return If(Decimal.TryParse(Text, value), value, 0)
        End Function
    
        Public Function AsInteger() As Integer
            Dim value As Integer
            Return If(Integer.TryParse(Text, value), value, 0)
        End Function
    
        Private WM_PASTE As Integer = &H302
        Protected Overrides Sub WndProc(ByRef m As Message)
            If m.Msg = WM_PASTE Then
                Dim clipboardData = Clipboard.GetDataObject()
                Dim input = CStr(clipboardData?.GetData(GetType(String)))
                Dim count As Integer = 0
    
                For Each c As Char In input
                    If c = _decimalSeparator Then
                        count += 1
                        If count > 1 Then
                            Return
                        End If
                    End If
                Next
    
                For Each character In input
    
                    If Not Char.IsControl(character) AndAlso Not Char.IsDigit(character) AndAlso character <> _decimalSeparator Then
                        m.Result = New IntPtr(0)
                        Return
                    End If
    
                Next
            End If
    
            MyBase.WndProc(m)
    
        End Sub
    End Class
    
    0 comments No comments

  3. KOZ6.0 6,300 Reputation points
    2024-06-12T12:18:18.92+00:00

    Would you like to try this?

    RestrictText.vb https://gist.github.com/KOZ60/48ba34bd6e0f0e66814e82ec833b2eb7

    The IsAllowChar method restricts the character that can be entered, and the IsValidText method determines whether the text is valid. Create a class that inherits from this:

    Public Class NumericBox
        Inherits RestrictText
    
        Protected Overrides Function IsAllowChar(inputChar As Char) As Boolean
            Return "0123456789.".IndexOf(inputChar) <> -1
        End Function
    
        Protected Overrides Function IsValidText(reflectsText As String) As Boolean
            Dim decValue As Decimal
            If String.IsNullOrEmpty(reflectsText) Then
                Return True
            End If
            If Not Decimal.TryParse(reflectsText, decValue) Then
                Return False
            End If
            Return MyBase.IsValidText(reflectsText)
        End Function
    
    End Class