I have the following code restricting the inputs of a 2-digit text box. I wanted to know if there is a way for me to prevent '00' from being entered if '0' exists already in the field:
Private Sub txtLLFiftyFifty_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtLLSwapQuestion.KeyPress, txtLLPlusOne.KeyPress, txtLLPhoneFriend.KeyPress, txtLLJumpQuestion.KeyPress, txtLLFiftyFifty.KeyPress, txtLLCrystalBall.KeyPress, txtLLAskExpert.KeyPress, txtLLAskAudience.KeyPress
If (Microsoft.VisualBasic.Asc(e.KeyChar) < 48) Or (Microsoft.VisualBasic.Asc(e.KeyChar) > 57) Then
e.Handled = True
End If
If (Microsoft.VisualBasic.Asc(e.KeyChar) = 8) Then
e.Handled = False
End If
End Sub
I've tried the following conditional but it doesn't seem to do anything:
If (Microsoft.VisualBasic.Asc(e.KeyChar) = 48) And Me.Text = "0" Then
e.Handled = False
End If
I have been using the following Subs to check and ensure data entered into a TextBox is numeric and it then gets converted to currency decimals in a form with a single CurrTextBox, however I have now been tasked to create a form with multiple CurrTextBox's.
How would I convert the following code to handle multiple calls. I suppose I can create a Public Sub that the data entered into a particular CurrTextBox calls... Ideas?
Private Sub CurrBox2_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
If (e.KeyCode >= Keys.D0 And e.KeyCode <= Keys.D9) OrElse (e.KeyCode >= Keys.NumPad0 And e.KeyCode <= Keys.NumPad9) OrElse e.KeyCode = Keys.Back Then
acceptableKey = True
Else
acceptableKey = False
End If
End Sub
' This sub handles the keypress inputs and ensures values are numeric only
Private Sub CurrBox2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
' Check for the flag being set in the KeyDown event.
If acceptableKey = False Then
' Stop the character from being entered into the control since it is non-numerical.
e.Handled = True
Return
Else
If e.KeyChar = Convert.ToChar(Keys.Back) Then
If strCurrency.Length > 0 Then
strCurrency = strCurrency.Substring(0, strCurrency.Length - 1)
End If
Else
strCurrency = strCurrency & e.KeyChar
End If
If strCurrency.Length = 0 Then
CurrBox2.Text = ""
ElseIf strCurrency.Length = 1 Then
CurrBox2.Text = "0.0" & strCurrency
ElseIf strCurrency.Length = 2 Then
CurrBox2.Text = "0." & strCurrency
ElseIf strCurrency.Length > 2 Then
CurrBox2.Text = strCurrency.Substring(0, strCurrency.Length - 2) & "." & strCurrency.Substring(strCurrency.Length - 2)
End If
CurrBox2.Select(CurrBox2.Text.Length, 0)
End If
e.Handled = True
End Sub
One event can handle multiple controls.
Just add more controls after Handles clause in your events and all of these to be handled.
Private Sub CurrBox2_KeyDown(ByVal sender As Object, ByVal e System.Windows.Forms.KeyEventArgs) Handles currbox1.keydown, currbox2.keydown, currbox3.keydown
If (e.KeyCode >= Keys.D0 And e.KeyCode <= Keys.D9) OrElse (e.KeyCode >= Keys.NumPad0 And e.KeyCode <= Keys.NumPad9) OrElse e.KeyCode = Keys.Back Then
acceptableKey = True
Else
acceptableKey = False
End If
End Sub
This way you need write those events only once.
I hope I was undertand your question right.
My problem:
I'm limiting a text box to 8 characters and showing a tooltip when it's exceeded (>8) rather than reached (=8). Using the .Maxlength function prevents the user from ever exceeding 8 characters so my >8 function is never fulfilled.
If I forgo the .Maxlength function and instead use .Substring to limit the input, my >8 function is fulfilled however the behavior differs from .Substring (the last rather than first 8 inputs are kept and I lose the alert sound).
It would a lot cleaner to be able to check for whenever .Maxlength is exceeded without affecting the first 8 inputs.
To reproduce:
In Visual Studio, in design mode, drag a text box and tooltip onto a fresh form.
Use the following as is:
Code:
Public Class Form1
Private Sub Textbox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
TextBox1.MaxLength = 8
If (Not IsNumeric(TextBox1.Text) And TextBox1.Text.Length > 0) Then
If ToolTip1.GetToolTip(TextBox1) = "" Then
ToolTip1.ToolTipTitle = "Input must be numeric!"
ToolTip1.Active = True
ToolTip1.IsBalloon = True
ToolTip1.ToolTipIcon = ToolTipIcon.Warning
ToolTip1.Show(vbNewLine, TextBox1, 45, -40)
End If
ElseIf TextBox1.Text.Length > 8 Then
'TextBox1.Text = TextBox1.Text.Substring(0, 8)
ToolTip1.IsBalloon = True
ToolTip1.ToolTipTitle = "8 character maximum!"
ToolTip1.Active = True
ToolTip1.ToolTipIcon = ToolTipIcon.Warning
ToolTip1.Show(vbNewLine, TextBox1, 45, -40)
Else
ToolTip1.Active = False
ToolTip1.Hide(TextBox1)
End If
End Sub
End Class
When you replace the text, it resets the caret, so move it back into place at the end:
TextBox1.Text = TextBox1.Text.Substring(0, 8)
TextBox1.Select(TextBox1.TextLength, 0)
It is better to supress the key if it is invalid:
Private Sub TextBox1_KeyPress(sender As System.Object, e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
Dim str As String
str = TextBox1.Text
str = str.Insert(TextBox1.SelectionStart, CStr(e.KeyChar))
If e.KeyChar = ChrW(Keys.Back) Then
HideToolTip()
ElseIf str.Length > 8 Then
ShowToolTip("8 character maximum!")
e.Handled = True
ElseIf Not IsNumeric(str) Then
ShowToolTip("Input must be numeric!")
e.Handled = True
Else
HideToolTip()
End If
End Sub
Private Sub HideToolTip()
If ToolTip1.GetToolTip(TextBox1) <> "" Then
ToolTip1.Active = False
ToolTip1.Hide(TextBox1)
End If
End Sub
Private Sub ShowToolTip(ByVal str As String)
'always check if tooltip is visible, to avoid inversion
If ToolTip1.GetToolTip(TextBox1) = "" Then
ToolTip1.ToolTipTitle = str
ToolTip1.Active = True
ToolTip1.IsBalloon = True
ToolTip1.ToolTipIcon = ToolTipIcon.Warning
ToolTip1.Show(vbNewLine, TextBox1, 45, -40, 1000)
End If
End Sub
EDIT
There is a minor "bug" in IsNumeric() function as it allows numeric with spaces and multiple "."
8..888 'is numeric
.9999 'is numeric
To solve everything:
Private Sub TextBox1_KeyPress(sender As System.Object, e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
Dim str As String = "0123456789."
If e.KeyChar = ChrW(Keys.Back) Then
HideToolTip()
ElseIf TextBox1.Text.Length = 8 Then
ShowToolTip("8 character maximum!")
e.Handled = True
ElseIf e.KeyChar = "." And (TextBox1.Text.Contains(".") Or TextBox1.SelectionStart = 0) Then 'supress a second "." or a first one
ShowToolTip("Input must be numeric!")
e.Handled = True
ElseIf Not str.Contains(CStr(e.KeyChar)) Then
ShowToolTip("Input must be numeric!")
e.Handled = True
Else
HideToolTip()
End If
End Sub
Add this after the substring call
TextBox1.SelectionStart = 8
i am using key press event. its working.. but i need to display decimal values. it only access with out ".(dot)"
If txtunit. Focused = True Then
If Not Char.IsNumber(e.KeyChar) And Not e.KeyChar = Chr(Keys.Back) Then
e.Handled = True
End If
End If
Try to include Chr(46) is which is for the Period.
If (Not Char.IsDigit(e.KeyChar) And Not e.KeyChar = Chr(Keys.Back) And Not e.KeyChar = Chr(46)) Then
e.Handled = True
End If
If you want to disable pasting in your textbox, you could do this also:
txtUnit.ShortcutsEnabled = False
Although above will also disable copying.
I'm wondering how I can get my textbox to only accept digits and dots, like:
123.45
or 115
or 218.16978
etc.
I already have the following code:
Private Sub TxtHStof_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TxtHStof.KeyPress
e.Handled = Not Char.IsDigit(e.KeyChar)
End Sub
But that only allows digits without the dots.
How can I change the code so it does allows the dots as well, but nothing else?
e.Handled = Not (Char.IsDigit(e.KeyChar) OR e.KeyChar=".")
The accepted solution doesn't cater for
Multiple entries of decimals for example "12....1234"
OS specific decimal separators
This works for me
Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
Dim DecimalSeparator As String = Application.CurrentCulture.NumberFormat.NumberDecimalSeparator
e.Handled = Not (Char.IsDigit(e.KeyChar) Or
Asc(e.KeyChar) = 8 Or
(e.KeyChar = DecimalSeparator And sender.Text.IndexOf(DecimalSeparator) = -1))
End Sub
You should use a MaskedTextBox - see here on how to set the format string (which allows you to restrict to digits and decimal point only)
http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask.aspx
With this code you can use ',' (Europe) and '.' (American) decimals.
Private Sub TGewicht_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TGewicht.KeyPress
e.Handled = Not (Char.IsDigit(e.KeyChar) Or Asc(e.KeyChar) = 8 Or ((e.KeyChar = "." Or e.KeyChar = ",") And (sender.Text.IndexOf(".") = -1 And sender.Text.IndexOf(",") = -1)))
End Sub
'****To Allow only Numbers with Decimal and BACKSPACE enabled****
If Not (Char.IsDigit(e.KeyChar) Or e.KeyChar = ".") And Not Char.IsControl(e.KeyChar) Then
e.Handled = True
End If
Coming from C# and not VB, I'm taking a stab at this, but would this work:
e.Handled = Not (Char.IsDigit(e.KeyChar) AndAlso e.KeyChar.Equals('.'))
Insert function in MODULE o FORM
Public Sub OnlyNumber(Ct As TextBox, MaxLength As Integer)
Ct.MaxLength = MaxLength
AddHandler Ct.KeyPress, AddressOf ValidarTeclaNumeros
End Sub
Private Sub ValidarTeclaNumeros(sender As Object, e As KeyPressEventArgs)
Dim Ct As TextBox
Ct = sender
If [Char].IsDigit(e.KeyChar) OrElse [Char].IsControl(e.KeyChar) Then
'ok
'e.Handled = True
ElseIf [Char].IsPunctuation(e.KeyChar) Then
If (Ct.Text.Contains(",") OrElse Ct.Text.Contains(".")) Then
e.Handled = True
End If
Else
e.Handled = True
End If
End Sub
In load form add this code for your control only numerical (and only one comma or doc)
OnlyNumber(txtControl, 10)
I started with mostly the same question, but I did care about being able to paste. While searching on the web for how to do this, I found that I really should handle:
Periods or commas as the decimal indicator, depending on how your OS is set up.
Only allowing keypresses that conform to the pattern, while still allowing cursor control characters like arrows and backspace.
Only allowing pastes into the TextBox that conform to the pattern. I chose to this in a manner that, when pasting, the code treats the pasted text as if the text was being keyed in, so pasting "a1b.c2d,e3f.g4h,i5j" into the TextBox would show up as "1.2345" if periods are your decimal indicator, and "12,345" if commas are your decimal indicator.
I tried the MaskedTextBox and really did not like it, as it enforced the decimal point location where I really just wanted to be able to freely fill in any numeric. I may have gone a little overboard using a RegEx for the pattern matching, but now I should be able to reuse this code pretty much anywhere.
Public Class frmMain
Dim RegexValidator As System.Text.RegularExpressions.Regex
Dim FormLoaded As Boolean = False
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim RegexDecimalPattern As String = Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
RegexDecimalPattern = IIf(RegexDecimalPattern = ".", "\.", RegexDecimalPattern)
RegexValidator = New System.Text.RegularExpressions.Regex("^\d*" & RegexDecimalPattern & "?\d*$", System.Text.RegularExpressions.RegexOptions.IgnoreCase)
FormLoaded = True
End Sub
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
' Code below is based on
' http://www.vbforums.com/showthread.php?626378-how-to-validate-textbox-allows-only-numeric-and-decimal-in-vb-net
' but was modified to be based on Regex patterns.
'
' Note that:
' KeyPress event validation covers data entry as it is being typed.
' TextChanged event validation covers data entry by cut/pasting.
If Char.IsControl(e.KeyChar) Then
'Allow all control characters.
Else
Dim Text = Me.TextBox1.Text
Dim SelectionStart = Me.TextBox1.SelectionStart
Dim SelectionLength = Me.TextBox1.SelectionLength
Text = Text.Substring(0, SelectionStart) & e.KeyChar & Text.Substring(SelectionStart + SelectionLength)
If Not RegexValidator.IsMatch(Text) Then e.Handled = True
End If
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
' If default text is used in a textbox, a TextChanged event occurs before
' RegexValidator is initialized during the Form Load, so we need to check.
If FormLoaded Then
' Note that:
' KeyPress event validation covers data entry as it is being typed.
' TextChanged event validation covers data entry by cut/pasting.
Dim Text = Me.TextBox1.Text
Dim ValidatedText As String = ""
Dim KeyChar As Char
For Each KeyChar In Text
If RegexValidator.IsMatch(ValidatedText + KeyChar) Then ValidatedText += KeyChar
Next
If (ValidatedText.Length > 0) And (TextBox1.Text <> ValidatedText) Then
Me.TextBox1.Text = ValidatedText
Me.TextBox1.SelectionStart += ValidatedText.Length
End If
End If
End Sub
End Class
im late for the party but here is my code
Private Sub LoanFeeTextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles LoanFeeTextBox.KeyPress
If Char.IsControl(e.KeyChar) Then
ElseIf Char.IsDigit(e.KeyChar) OrElse e.KeyChar = "."c Then
If LoanFeeTextBox.TextLength = 12 And LoanFeeTextBox.Text.Contains(".") = False Then
LoanFeeTextBox.AppendText(".")
ElseIf e.KeyChar = "." And LoanFeeTextBox.Text.IndexOf(".") <> -1 Then
e.Handled = True
ElseIf Char.IsDigit(e.KeyChar) Then
If LoanFeeTextBox.Text.IndexOf(".") <> -1 Then
If LoanFeeTextBox.Text.Length >= LoanFeeTextBox.Text.IndexOf(".") + 3 Then
e.Handled = True
End If
End If
End If
Else
e.Handled = True
End If
End Sub
Private Sub TextBox2_KeyPress(
ByVal sender As Object,
ByVal e As System.Windows.Forms.KeyPressEventArgs
) Handles TextBox2.KeyPress
e.Handled = Not (Char.IsDigit(e.KeyChar) Or e.KeyChar = "." Or Asc(e.KeyChar) = 8)
End Sub
Just adding another solution. This code restricts user to entering only one "." decimal point, only two places beyond the decimal point, can set how many digits you want to use (currently I have it set to only allow up to to 5 whole numbers before the decimal. Also allows use of backspace and delete. That way they can't fat finger an extra "." and end up with something like "45.5.5".
If Char.IsControl(e.KeyChar) Then
ElseIf Char.IsDigit(e.keyChar) OrElse e.keyChar = "."c Then
If Amount_FundedTextBox.TextLength = 5 And Amount_FundedTextBox.Text.Contains(".") = False Then
Amount_FundedTextBox.AppendText(".")
ElseIf e.KeyChar = "." And Amount_FundedTextBox.Text.IndexOf(".") <> -1 Then
e.Handled = True
ElseIf Char.IsDigit(e.KeyChar) Then
If Amount_FundedTextBox.Text.IndexOf(".") <> -1 Then
If Amount_FundedTextBox.Text.Length >= Amount_FundedTextBox.Text.IndexOf(".") + 3 Then
e.Handled = True
End If
End If
End If
Else
e.Handled = True
End If
You can restrict character entries in your textboxes by adding a "KeyPress" handler (from TextBox properties) and specifying allowable characters. If the character is "handled" then it is not permitted.
Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox.KeyPress
Dim txt As TextBox = CType(sender, TextBox)
If Not ((Char.IsDigit(e.KeyChar)) Or (e.KeyChar = "E") Or (e.KeyChar = "e") Or (e.KeyChar = "-")) Then e.Handled = True
If e.KeyChar = Chr(8) Then e.Handled = False 'allow Backspace
If e.KeyChar = "." And txt.Text.IndexOf(".") = -1 Then e.Handled = False 'allow single decimal point
If e.KeyChar = Chr(13) Then GetNextControl(txt, True).Focus() 'Enter key moves to next control
End Sub
Private Sub TextBox4_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox4.KeyPress
' its worked for only number with point and worked backspace
If Not Char.IsDigit(e.KeyChar) And Not e.KeyChar = "." Then
e.Handled = True
End If
If e.KeyChar = "." And TextBox4.Text.IndexOf(".") <> -1 Then
e.Handled = True
End If
If e.KeyChar = "." Then
e.Handled = False
End If
If e.KeyChar = Chr(Keys.Back) Then
e.Handled = False
End If
If Char.IsDigit(e.KeyChar) Then
If TextBox4.Text.IndexOf(".") <> -1 Then
If TextBox4.Text.Length >= TextBox4.Text.IndexOf(".") + 3 Then 'replace 2 for greater numbers after decimal point
e.Handled = True
TextBox4.Focus()
End If
End If
End If
' is for only digit with back space
e.Handled = Not Char.IsDigit(e.KeyChar)
If e.KeyChar = Chr(Keys.Back) Then
e.Handled = False
End If
If Char.IsDigit(e.KeyChar) Then
If TextBox4.Text.IndexOf(".") <> -1 Then
If TextBox4.Text.Length >= TextBox4.Text.IndexOf(".") + 3 Then 'replace 2 for greater numbers after decimal point
e.Handled = True
TextBox4.Focus()
End If
End If
End If
End Sub
Dim e As System.Windows.Forms.KeyPressEventArgs
If Asc(e.KeyChar) < 48 Or Asc(e.KeyChar) > 57 Then
e.Handled = True
Else
e.Handled = False
End If