I have been searching the internet for ideas on how to restrict a VB.Net System.Windows.Forms.TextBox control to only accept positive Long or positive Double numeric values. I think I have come up with a good control set up, primarily based on this post on msdn. The code within the KeyPress and Leave events below is generic and can be pasted into any Textbox KeyPress and Leave events to produce the behaviors described below. I am posting this in case it helps others and also to see if anyone has a more elegant way of doing this.For this example, the behavior criteria of my Long Textbox are as follows:1. When the user finishes editing in the Textbox the value of the Textbox must be a Long interger that is positive and greater than or equal to 1 (in this example the Textbox represents an annual average daily trip count which cannot be negative and which is used as a divisor in an equation, so at least 1 annual average daily trip must occur on the road for a valid analysis).2. From the keyboard the user must only be able to type numbers.3. The user may paste text into the Textbox. This introduces the possibility for insertion of negative numbers, floating values, and invalid entries which must be resolved in the following ways:a. If a negative number is pasted into the Textbox, it must be reset to its absolute value.b. If a floating number is pasted into the Textbox, it must be rounded to a whole interger.c. If the user pastes invalid text into the Textbox and does not correct an invalid entry prior to leaving the Textbox, the user will be permitted to exit the textbox, but the invalid value will be replaced by the minimum default value (in this case 1).4. If a user attempts to leave the Textbox with a blank entry or an entry of 0, the user is permitted to leave but the textbox will be completed using the minimum default value (in this case 1).5. Numbers must always be corrected to a conventional format when the user leaves the Textbox. In other words, a user may enter a value of 023 into the Textbox, but when he exits the Textbox it must appear as 23.Here is the code that implements this behavior. The Textbox in this specific example is named txtAADT; however, the code written within the KeyPress and Leave Subs is generic and can be pasted into these two events for any other Textbox to implement the same behavior.Imports System.Math
Private Sub txtAADT_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtAADT.KeyPress
# If the keystroke is not a numeric digit, the keystroke will be disregarded. Code works for any Textbox KeyPress event.
If Not (Char.IsDigit(e.KeyChar) Or Char.IsControl(e.KeyChar)) Then
e.Handled = True
End If
End Sub
Private Sub txtAADT_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtAADT.Leave
# User has completed their entry and is leaving the Textbox.
# Create a Textbox variable to make the code below generic so that it can be pasted into any Textbox Leave event
Dim tbx As System.Windows.Forms.TextBox = sender
Dim value As Double
If Not Double.TryParse(tbx.Text, value) Then
# The user did not correct an invalid entry so replace it with 1
tbx.Text = 1
ElseIf value < -1 Then
# The user pasted a negative value, so make sure it is rounded and take its absolute value
tbx.Text = Abs(CLng(value))
ElseIf value < 1 Then
# The user has entered 0 or pasted in a value between -1 and 1, so replace with minimum value of 1
tbx.Text = 1
ElseIf value = vbNull Then
# The user has blanked out the Textbox, so fill in the Textbox with the minimum value of 1
tbx.Text = 1
Else
# The user has entered a valid postive number, so make sure it is rounded and appears as a conventional number
tbx.Text = CLng(value)
End If
End Sub
The positive Double Textbox has similar requirements to the positive Long Textbox, but it allows an optional single decimal point to be inserted to create non-integer values. (The code is not designed at this time to respond to local Cultural settings for the decimal character, so that would be a nice enhancement if anyone cares to suggest the code required to do that.) The following additional or different behaviors are implement with the positive Double Textbox:1. When the user finishes editing in the Textbox the value of the Textbox must be a Double value that is positive and greater than or equal to 0 (in this example the Textbox represents a Distance of offset from an intersection which cannot be negative, but which may be 0 where no offset is desired).2. From the keyboard the user must only be able to type numbers and at most one decimal character.3. The user may paste text into the Textbox. This introduces the possibility for insertion of negative numbers and invalid entries which must be resolved in the following ways:a. If a negative number is pasted into the Textbox, it must be reset to its absolute value.b. If the user pastes invalid text into the Textbox and does not correct an invalid entry prior to leaving the Textbox, the user will be permitted to exit the textbox, but the invalid value will be replaced by the minimum default value (in this case 0).4. If a user attempts to leave the Textbox with a blank entry, the user is permitted to leave but the textbox will be completed using the minimum default value (in this case 0).5 A maximum of 4 fractional digits are permitted. Any fractional digits beyond that must be rounded. (This is due to the maximum resolution of the data)6. Numbers must always be corrected to a conventional format when the user leaves the Textbox. In other words, a user may enter a value of 023.123456 into the Textbox, but when he exits the Textbox it must appear as 23.1235.Here is the code for the positive Double Textbox. The Textbox in this specific example is named txtDistance1; however, the code written within the KeyPress and Leave Subs is generic and can be pasted into these two events for any other Textbox to implement the same behavior.Imports System.Math
Private Sub txtDistance1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtDistance1.KeyPress
# Create a Textbox variable so that the code within this KeyPress event is generic for all positive Double Textboxes.
Dim tbx As System.Windows.Forms.TextBox = sender
If Not (Char.IsDigit(e.KeyChar) Or Char.IsControl(e.KeyChar) Or (e.KeyChar = "." And tbx.Text.IndexOf(".") < 0) Or (e.KeyChar = "." And tbx.Text.IndexOf(".") >= 0 And tbx.SelectionLength > 0 And tbx.SelectionStart <= tbx.Text.IndexOf(".") And tbx.SelectionStart + tbx.SelectionLength > tbx.Text.IndexOf("."))) Then
# Explanation: Prevent the keystroke if it is not a numeric digit, a non-printable character such as a Backspace, or a decimal point where no decimal point exists in the Textbox or where the existing decimal point is contained in a text selection that will be overwritten by the new decimal point.
e.Handled = True
End If
End Sub
Private Sub txtDistance1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtDistance1.Leave
# User has completed their entry and is leaving the Textbox
# Create a Textbox variable so that the code below is generic and can be pasted into any Textbox Leave event
Dim tbx As System.Windows.Forms.TextBox = sender
Dim value As Double
If Not Double.TryParse(tbx.Text, value) Then
# Textbox value is invalid, so replace it with the minimum default value (in this case 0)
tbx.Text = 0
ElseIf value = vbNull Then
# The user has blanked out the Textbox, so fill in the Textbox with the minimum value of 0
tbx.Text = 0
ElseIf value >= 0 Then
# value is positive so round to 4 decimal places and correct to conventional format
tbx.Text = Round(value, 4)
Else
# value is negative so round to 4 decimal places, apply the absolute value and correct to conventional format
tbx.Text = Abs(Round(value, 4))
End If
End Sub
Again, I hope this helps.