locked
Only allow users to enter a number in textboxes. Display and error message if a number is not entered. RRS feed

  • 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 Sub
    Wednesday, 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