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