Answered by:
Only allow users to enter a number in textboxes. Display and error message if a number is not entered.

Question
-
I am doing an imperial to metric length converter and I am struggling to create an error message if a number is not inputted. Does anyone have any suggestions? Here is the code:
Public Class Form1
Dim inchesVal, inchesMm, inchesCm, inchesM, inchesKm, footVal, footMm, footCm,
footM, footKm, yardsVal, yardsMm, yardsCm, yardsM, yardsKm, milesVal, milesM, milesKm As Integer
Dim strTextInput As String
Dim decTextInput As Decimal
Dim KeyChar As Char
Private Sub inchCon_Click() Handles inchCon.Click
inchesVal = Val(inchVal.Text)
inchesMm = Val(inchMm.Text)
inchesCm = Val(inchCm.Text)
inchesM = Val(inchM.Text)
inchesKm = Val(inchKm.Text)
inchMm.Text = inchVal.Text / 0.03937
inchCm.Text = inchVal.Text / 0.3937
inchM.Text = inchVal.Text / 39.37
inchKm.Text = inchVal.Text / 3937
strTextInput = inchVal.Text
End Sub
Private Sub feetCon_Click() Handles feetCon.Click
footVal = Val(feetVal.Text)
footMm = Val(feetMm.Text)
footCm = Val(feetCm.Text)
footM = Val(feetM.Text)
footKm = Val(feetKm.Text)
feetMm.Text = feetVal.Text / 0.0032808
feetCm.Text = feetVal.Text / 0.032808
feetM.Text = feetVal.Text / 3.2808
feetKm.Text = feetVal.Text / 3280.8
End Sub
Private Sub yardCon_Click() Handles yardCon.Click
yardsVal = Val(yardVal.Text)
yardsMm = Val(yardMm.Text)
yardsCm = Val(yardCm.Text)
yardsM = Val(yardM.Text)
yardsKm = Val(yardKm.Text)
yardMm.Text = yardVal.Text / 0.0010936
yardCm.Text = yardVal.Text / 0.010936
yardM.Text = yardVal.Text / 1.0936
yardKm.Text = yardVal.Text / 1093.6
End Sub
Private Sub mileCon_Click() Handles mileCon.Click
milesVal = Val(mileVal.Text)
milesM = Val(mileM.Text)
milesKm = Val(mileKm.Text)
mileM.Text = mileVal.Text / 0.00062137
mileKm.Text = mileVal.Text / 0.62137
End Sub
Private Sub btnClear_Click(sender As System.Object, e As System.EventArgs) Handles btnClear.Click
inchVal.Text = ""
inchMm.Text = ""
inchCm.Text = ""
inchM.Text = ""
inchKm.Text = ""
feetVal.Text = ""
feetMm.Text = ""
feetCm.Text = ""
feetM.Text = ""
feetKm.Text = ""
yardVal.Text = ""
yardMm.Text = ""
yardCm.Text = ""
yardM.Text = ""
yardKm.Text = ""
mileVal.Text = ""
mileM.Text = ""
mileKm.Text = ""
End SubWednesday, May 8, 2013 11:29 AM
Answers
-
Hello,
First off I would suggest you set Option Strict On under Project properties which afterwards there will be serveral errors in the code above to fix. Second, instead of using Val use TryParse
TryParse example, you should not be using Integers.
Dim FeetValue As Decimal = 0 If Decimal.TryParse(feetVal.Text, FeetValue) Then ' Okay to use feetVal.Text Else ' Not okay to use feelval.text as decimal End If
For checking if a TextBox Text is empty the following class when added to your project then add the class to the form allows an error message to be shown when a value for a specfic TextBox is empty. This class works similar to a ToolTip.
Screenshot where the second TextBox has been setup to not allow empty entries. The tooltip text is set by you the developer.
Imports System.ComponentModel Imports System.Windows.Forms <Drawing.ToolboxBitmap(GetType(IsRequiredProvider), "your_image.bmp"), _ System.ComponentModel.DesignerCategoryAttribute("Code"), _ ProvideProperty("IsRequiredMessage", GetType(Control)), _ ProvideProperty("AllowEmptyValue", GetType(Control)), _ ProvideProperty("AllowEmptyErrorMessage", GetType(Control))> _ Public Class SimpleTextBoxProvider Inherits System.ComponentModel.Component Implements IExtenderProvider Friend htProvidedProperties As New Hashtable Private MissingMessages As New Hashtable Private mEnabled As Boolean = True Public Sub New(ByVal Container As System.ComponentModel.IContainer) MyClass.New() Container.Add(Me) End Sub Public Sub New() MyBase.New() InitializeComponent() End Sub Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub Private components As System.ComponentModel.IContainer Friend WithEvents errOutOfRange As System.Windows.Forms.ErrorProvider <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Me.errOutOfRange = New System.Windows.Forms.ErrorProvider Me.errOutOfRange.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink End Sub Private Class ValidatorProperties Public AllowEmptyValue As Boolean = True Public AllowEmptyErrorMessage As String = "Can not be empty" End Class Private Function GetControlFromHashtable(ByVal ctrl As Control) As ValidatorProperties If htProvidedProperties.Contains(ctrl) Then Return DirectCast(htProvidedProperties(ctrl), ValidatorProperties) Else Dim ProvidedProperties As New ValidatorProperties 'AddHandler CType(ctrl, TextBox).KeyPress, AddressOf This_KeyPress htProvidedProperties.Add(ctrl, ProvidedProperties) Return ProvidedProperties End If End Function <Category("Behavior"), _ DefaultValue(True)> _ Public Property Enabled() As Boolean Get Return mEnabled End Get Set(ByVal Value As Boolean) mEnabled = Value End Set End Property Public Function CanExtend(ByVal client_control As Object) As Boolean Implements IExtenderProvider.CanExtend Return (TypeOf client_control Is TextBox) End Function <Category("Validation")> _ <Description("Determine if text can be left empty")> _ Public Function GetAllowEmptyValue(ByVal ctrl As Control) As Boolean Return CType(GetControlFromHashtable(ctrl).AllowEmptyValue, Boolean) End Function <Category("Validation")> _ Public Sub SetAllowEmptyValue(ByVal ctrl As Control, ByVal value As Boolean) GetControlFromHashtable(ctrl).AllowEmptyValue = value End Sub <Category("Validation")> _ <Description("Error message to display if not valid")> _ Public Function GetAllowEmptyErrorMessage(ByVal ctrl As Control) As String Return CType(GetControlFromHashtable(ctrl).AllowEmptyErrorMessage, String) End Function <Category("Validation")> _ Public Sub SetAllowEmptyErrorMessage(ByVal ctrl As Control, ByVal value As String) GetControlFromHashtable(ctrl).AllowEmptyErrorMessage = value End Sub <Category("Validation"), _ DefaultValue("")> _ Public Function GetIsRequiredMessage(ByVal client_control As Control) As String If MissingMessages.Contains(client_control) Then Return DirectCast(MissingMessages(client_control), String) Else Return Nothing End If End Function <Category("Validation"), _ DefaultValue("")> _ Public Sub SetIsRequiredMessage(ByVal client_control As Control, ByVal missing_message As String) If MissingMessages.Contains(client_control) Then MissingMessages.Remove(client_control) RemoveHandler client_control.Validating, AddressOf Client_Validating End If If Not (missing_message Is Nothing) Then If missing_message.Length > 0 Then MissingMessages.Add(client_control, missing_message) AddHandler client_control.Validating, AddressOf Client_Validating End If End If End Sub Private Sub Client_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) If Not mEnabled Then Exit Sub End If ValidateTextBox(DirectCast(sender, TextBox)) End Sub Private Sub ValidateTextBox(ByVal sender As TextBox) If sender.Text.Trim.Length > 0 Then Me.errOutOfRange.SetError(sender, "") Else ' It's blank. Dim missing_message As String = "" Me.errOutOfRange.SetError(sender, DirectCast(MissingMessages(sender), String)) End If End Sub Private Sub This_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then SendKeys.Send("{TAB}") e.Handled = True End If End Sub Public Function HasError() As Boolean If Not mEnabled Then Return False End If ' Make sure all controls have been validated. For Each TB As TextBox In MissingMessages.Keys ValidateTextBox(TB) Next TB ' Find the first control in the tab order with an error. Dim FirstTextBox As TextBox = Nothing Dim FirstTabIndex As Integer = Integer.MaxValue For Each TB As TextBox In MissingMessages.Keys ' See if the control has an error. If errOutOfRange.GetError(TB).Length > 0 Then If TB.TabIndex < FirstTabIndex Then FirstTextBox = TB FirstTabIndex = TB.TabIndex End If End If Next ' See if any control has an error. If Not (FirstTextBox Is Nothing) Then FirstTextBox.Focus() Return True End If Return False End Function End Class
Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.
- Edited by KareninstructorMVP Wednesday, May 8, 2013 12:51 PM Added screenshot
- Proposed as answer by Devon_Nullman Thursday, May 9, 2013 3:19 PM
- Marked as answer by Youen Zen Tuesday, May 28, 2013 6:06 AM
Wednesday, May 8, 2013 11:52 AM
All replies
-
Hello,
First off I would suggest you set Option Strict On under Project properties which afterwards there will be serveral errors in the code above to fix. Second, instead of using Val use TryParse
TryParse example, you should not be using Integers.
Dim FeetValue As Decimal = 0 If Decimal.TryParse(feetVal.Text, FeetValue) Then ' Okay to use feetVal.Text Else ' Not okay to use feelval.text as decimal End If
For checking if a TextBox Text is empty the following class when added to your project then add the class to the form allows an error message to be shown when a value for a specfic TextBox is empty. This class works similar to a ToolTip.
Screenshot where the second TextBox has been setup to not allow empty entries. The tooltip text is set by you the developer.
Imports System.ComponentModel Imports System.Windows.Forms <Drawing.ToolboxBitmap(GetType(IsRequiredProvider), "your_image.bmp"), _ System.ComponentModel.DesignerCategoryAttribute("Code"), _ ProvideProperty("IsRequiredMessage", GetType(Control)), _ ProvideProperty("AllowEmptyValue", GetType(Control)), _ ProvideProperty("AllowEmptyErrorMessage", GetType(Control))> _ Public Class SimpleTextBoxProvider Inherits System.ComponentModel.Component Implements IExtenderProvider Friend htProvidedProperties As New Hashtable Private MissingMessages As New Hashtable Private mEnabled As Boolean = True Public Sub New(ByVal Container As System.ComponentModel.IContainer) MyClass.New() Container.Add(Me) End Sub Public Sub New() MyBase.New() InitializeComponent() End Sub Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub Private components As System.ComponentModel.IContainer Friend WithEvents errOutOfRange As System.Windows.Forms.ErrorProvider <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Me.errOutOfRange = New System.Windows.Forms.ErrorProvider Me.errOutOfRange.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink End Sub Private Class ValidatorProperties Public AllowEmptyValue As Boolean = True Public AllowEmptyErrorMessage As String = "Can not be empty" End Class Private Function GetControlFromHashtable(ByVal ctrl As Control) As ValidatorProperties If htProvidedProperties.Contains(ctrl) Then Return DirectCast(htProvidedProperties(ctrl), ValidatorProperties) Else Dim ProvidedProperties As New ValidatorProperties 'AddHandler CType(ctrl, TextBox).KeyPress, AddressOf This_KeyPress htProvidedProperties.Add(ctrl, ProvidedProperties) Return ProvidedProperties End If End Function <Category("Behavior"), _ DefaultValue(True)> _ Public Property Enabled() As Boolean Get Return mEnabled End Get Set(ByVal Value As Boolean) mEnabled = Value End Set End Property Public Function CanExtend(ByVal client_control As Object) As Boolean Implements IExtenderProvider.CanExtend Return (TypeOf client_control Is TextBox) End Function <Category("Validation")> _ <Description("Determine if text can be left empty")> _ Public Function GetAllowEmptyValue(ByVal ctrl As Control) As Boolean Return CType(GetControlFromHashtable(ctrl).AllowEmptyValue, Boolean) End Function <Category("Validation")> _ Public Sub SetAllowEmptyValue(ByVal ctrl As Control, ByVal value As Boolean) GetControlFromHashtable(ctrl).AllowEmptyValue = value End Sub <Category("Validation")> _ <Description("Error message to display if not valid")> _ Public Function GetAllowEmptyErrorMessage(ByVal ctrl As Control) As String Return CType(GetControlFromHashtable(ctrl).AllowEmptyErrorMessage, String) End Function <Category("Validation")> _ Public Sub SetAllowEmptyErrorMessage(ByVal ctrl As Control, ByVal value As String) GetControlFromHashtable(ctrl).AllowEmptyErrorMessage = value End Sub <Category("Validation"), _ DefaultValue("")> _ Public Function GetIsRequiredMessage(ByVal client_control As Control) As String If MissingMessages.Contains(client_control) Then Return DirectCast(MissingMessages(client_control), String) Else Return Nothing End If End Function <Category("Validation"), _ DefaultValue("")> _ Public Sub SetIsRequiredMessage(ByVal client_control As Control, ByVal missing_message As String) If MissingMessages.Contains(client_control) Then MissingMessages.Remove(client_control) RemoveHandler client_control.Validating, AddressOf Client_Validating End If If Not (missing_message Is Nothing) Then If missing_message.Length > 0 Then MissingMessages.Add(client_control, missing_message) AddHandler client_control.Validating, AddressOf Client_Validating End If End If End Sub Private Sub Client_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) If Not mEnabled Then Exit Sub End If ValidateTextBox(DirectCast(sender, TextBox)) End Sub Private Sub ValidateTextBox(ByVal sender As TextBox) If sender.Text.Trim.Length > 0 Then Me.errOutOfRange.SetError(sender, "") Else ' It's blank. Dim missing_message As String = "" Me.errOutOfRange.SetError(sender, DirectCast(MissingMessages(sender), String)) End If End Sub Private Sub This_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then SendKeys.Send("{TAB}") e.Handled = True End If End Sub Public Function HasError() As Boolean If Not mEnabled Then Return False End If ' Make sure all controls have been validated. For Each TB As TextBox In MissingMessages.Keys ValidateTextBox(TB) Next TB ' Find the first control in the tab order with an error. Dim FirstTextBox As TextBox = Nothing Dim FirstTabIndex As Integer = Integer.MaxValue For Each TB As TextBox In MissingMessages.Keys ' See if the control has an error. If errOutOfRange.GetError(TB).Length > 0 Then If TB.TabIndex < FirstTabIndex Then FirstTextBox = TB FirstTabIndex = TB.TabIndex End If End If Next ' See if any control has an error. If Not (FirstTextBox Is Nothing) Then FirstTextBox.Focus() Return True End If Return False End Function End Class
Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.
- Edited by KareninstructorMVP Wednesday, May 8, 2013 12:51 PM Added screenshot
- Proposed as answer by Devon_Nullman Thursday, May 9, 2013 3:19 PM
- Marked as answer by Youen Zen Tuesday, May 28, 2013 6:06 AM
Wednesday, May 8, 2013 11:52 AM -
Hi,
You could use the textbox KeyPress event to only allow numbers to be entered. This will only allow 0 - 9 and a decimal point to be typed in the textbox.
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress Dim valid As String = "0123456789." If Not valid.Contains(e.KeyChar) Then e.Handled = True MessageBox.Show("Invalid character. Please enter numbers only.", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Error) End If End Sub
Wednesday, May 8, 2013 12:08 PM -
Since you have a lot of TextBoxes maybe this will work better for you.
Option Strict On Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim textBoxes = Me.Controls.OfType(Of TextBox)() For Each txt In textBoxes AddHandler txt.KeyPress, AddressOf txtKeyPress Next End Sub Private Sub txtKeyPress(sender As Object, e As KeyPressEventArgs) Dim valid As String = "0123456789." If Not valid.Contains(e.KeyChar) Then e.Handled = True MessageBox.Show("Invalid character. Please enter numbers only.", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Error) End If End Sub End Class
You've taught me everything I know but not everything you know.
Thursday, May 9, 2013 1:48 AM -
If you do not have other textboxes other than the ones listed in your btnClear button event then this would make your btnClear code a little smaller. :)
Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click Dim textboxes = Me.Controls.OfType(Of TextBox)() For Each tb As TextBox In textboxes tb.Clear() Next End Sub
Thursday, May 9, 2013 2:39 AM -
The code posted above will allow more than one decimal point.
The following code will only permit input of digits with a single decimal point. It will also allow the backspace key, and negative numbers. The Enter key will move the focus to the next control in Tab order. Use only the statements you need for your program:
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress If Not Char.IsDigit(e.KeyChar) Then e.Handled = True If e.KeyChar = Chr(8) Then e.Handled = False 'allow Backspace If e.KeyChar = "-" And TextBox1.SelectionStart = 0 Then e.Handled = False 'allow negative number If e.KeyChar = "." And TextBox1.Text.IndexOf(".") = -1 Then e.Handled = False 'allow single decimal point If e.KeyChar = Chr(13) Then GetNextControl(TextBox1, True).Focus() 'Enter key moves to next control End Sub
Solitaire
Thursday, May 9, 2013 4:44 AM -
try this
if isnumeric(textbox.text) then blablabla elseif textbox1.text="" then msgbox("Please enter something) else msgbox("only numberics are allow) end if
Thursday, May 9, 2013 5:32 AM -
When I type a letter into the textbox, the message box does not display. Instead an error displays which says 'Conversion from string "d" to type 'Double' is not valid.' This line of my code is then highlighted : inchMm.Text = inchVal.Text / 0.03937.
Ryan Dodd
Wednesday, May 15, 2013 11:22 AM -
Thats because you need to ether use TryParse to convert it to a number or make the textbox so that only numbers can be used in it. Also you are trying to divide a string by a number. You will need to convert the text (String) to a number (Double) before doing any math functions to it and then convert it back to a string before assigning the number back to the textbox.
Dim ival As Double = 0 Double.TryParse(inchVal.Text, ival) inchMm.Text = (ival / 0.03937).ToString
- Edited by IronRazerz Wednesday, May 15, 2013 11:40 AM
Wednesday, May 15, 2013 11:31 AM -
I also forgot to tell you that you really should turn on Option Strict and Option Explicit. You can do that in the VB Options or by adding these two lines as the very first two lines of your code
Option Strict On Option Explicit On Public Class Form1 'Your Program Code End Class
This will put a little blue line under the code that has errors of type conversion. You will see a little red box on the end of the blue line that you can put the mouse over and that will make a red box with a (!) on it. Click on that red box and most of the time it will give you a choice of how you can fix the error. It is not correct 100% of the time but, i would say it is at least 90% of the time.
Wednesday, May 15, 2013 11:55 AM -
Using the KeyPress event doesn't work if the user pastes something into the textbox.
"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein
Wednesday, May 15, 2013 12:05 PM