שתף באמצעות


How Do I Restrict/Limit A TextBox To Numerical Values ONLY and No Strings or Chars?

Question

Wednesday, December 25, 2013 6:50 AM

    Private Sub txtStreams_TextChanged(sender As Object, e As EventArgs) Handles txtStreams.TextChanged

        Try

            REM Check and test if what is written is a number:
            If txtStreams.Text = IsNumeric(txtStreams) Then

            Else
                MsgBox("You can only use numerical values to fill in this text box", vbOKOnly + vbInformation, "Streams")
                txtStreams.Clear()
                txtStreams.Focus()

            End If

        Catch ex As Exception

        End Try

    End Sub

Hi everybody,

I'm Edward and I've got a problem.

I have a textbox(txtStreams) and I want the user of the program to input a number not more than 12, not less than 1 in it.

Problem is:

How do I limit the user from typing strings in the textbox using the txtStreams_TextChanged() event?

Like, immediately the user types a character which isn't a numerical value, a message box pops up.

I've tried to use IsNumeric() but that does exactly the opposite of what I want(so angry with it!). It makes the msgbox pop up when a user types in a numeric value, which is the opposite of what I want.

You know, In java SE, I'm used to using "!" to mean something like NOT. I saw NOT in VB.NET too, but even after learning about it, I'm finding it hard to apply in this problem.

Attached here is my code snippet currently.

And before I forget, I'm not that new to VB, but I'd rather say am new to VB.NET.

I've used VB 06 before and for a long time, so right now, I'm in the transition process from VB to VB.NET, and pretty sure I'll be great in VB.NET coz it's so awesome and fun and more powerful!

I appreciate your help, answers, votes, suggestions and trolls!

Regards,

Edward Quixote.

All replies (22)

Wednesday, December 25, 2013 12:30 PM ✅Answered | 1 vote

hi Edward,

my suggestion is as follow instead of 'TextChanged' event.

Private Sub txtStreams_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtStreams.KeyPress

try

    Dim allowedChars As String = "0123456789$,"

    If allowedChars.IndexOf(e.KeyChar) = -1 Then
        ' Invalid Character
        e.Handled = True

 MsgBox("You can only use numerical values to fill in this text box", vbOKOnly + vbInformation, "Streams")
                txtStreams.Clear()
                txtStreams.Focus()

    End If

 

Catchex AsException

            MsgBox(ex.Message)      

EndTry

End Sub

also about ' input a number not more than 12' you can use nvarchar(12) datatype in database(sql).

regards.


Saturday, April 12, 2014 4:47 PM ✅Answered

Guys I got another possible solution, which I prefer using in an IF Statement/Condition.

If IsNumeric(txtA.Text) = True Then

MsgBox(My.Resources.SStreamCharError, vbOKOnly + vbCritical, My.Resources.STitleSetUpError)
txtA.Clear()
txtA.Focus()

End If

You can either use TRUE or FALSE.(It's just an example).

Regards,

Edward Quixote.


Wednesday, December 25, 2013 7:49 AM

Hi ,

    Refer this following code.

private void txtStreams_KeyPress(object sender, KeyPressEventArgs e)
        {
            if(char.IsDigit(e.KeyChar))
            {
                if (txtStreams.Text != String.Empty)
                {
                    StringBuilder strbldr = new StringBuilder();
                    strbldr.Append(txtStreams.Text);
                    strbldr.Append(e.KeyChar);

                    if (CheckInput(Convert.ToInt32(strbldr.ToString())))
                    {
                        e.Handled = false; //Do not reject the input
                    }
                    else
                    {
                        e.Handled = true; //Reject the input
                    }
                }
                else
                {
                    e.Handled = false; //Do not reject the input since this is first char
                }
            }
            else
            {
                e.Handled = true; //Reject the input
            }
        }
        public bool CheckInput(Int32 iVal)
        {
            if ((iVal >= 1) && (iVal <= 12))
            {
                return true;
            }
            return false;
        }

Thanks and Regards, vinothkumar.A


Wednesday, December 25, 2013 9:27 AM | 1 vote

If the legal input is a range of integer 1 - 12 then you may consider using as combobox dropdownlist or a listbox that appears and disappears.

But when using textboxes for input, it can be annoying to have messageboxes popping up every time you make an input error. Following is a very simple model which only beeps at the user when they put something illegal in the textbox, and returns the textbox with it's most recent legal entry. The string variable H (history) keeps record of the last legal entry to the textbox. If you press [enter] the textbox validates and focus is shifted to the next control.

Public Class Form11
    Dim H As String = "1"

    Private Sub TextBox1_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        If e.KeyChar = Chr(13) Then
            e.Handled = True
            TextBox2.Select()
        End If
    End Sub

    Private Sub TextBox1_Leave(sender As Object, e As System.EventArgs) Handles TextBox1.Leave
        Dim S As String = TextBox1.Text
        Dim I As Integer
        If S = "" Then Beep() : TextBox1.Text = H : Exit Sub
        Try
            I = CInt(S)
        Catch ex As Exception
            Beep() : TextBox1.Text = H : Exit Sub
        End Try
        If I < 1 Or I > 12 Then Beep() : TextBox1.Text = H : Exit Sub
        H = I.ToString
        TextBox1.Text = H
    End Sub
End Class

Leon C Stanley - - A dinky di VBer - - Code is like fresh baked bread - it goes stale after a while - - so why try to immortalize it ? and turn it into a Class? ^^ :-)


Wednesday, December 25, 2013 9:29 AM

Hey Vin,

Thanks for your contribution, but it's in Java instead of VB.NET.

I needed help in VB.NET.

Regard,

Edward Quixote.


Wednesday, December 25, 2013 9:49 AM

Hey, Leon,

Your code worked just right.

Then I figured out, the history(H) function will make, maybe, the user input or submit information that he/she didn't desire, especially if their computers have no speakers to produce the beep sound or if they are just the ignorant or the 'less-concentrating' humans. You get? It might be a disadvantage both to them(user) and you as the developer(when they submit undesired information).

So I decided to go by your combo box suggestion, and it works just great.

Thanks a lot.

But if I may ask, is Exit Sub at the end of an If Statement the same as End If?

Regards,

Edward Quixote.


Wednesday, December 25, 2013 1:05 PM

Be aware that latin characters and special characters are also chars and can be in a string.

You mean probably only arabian numeric chars 

You can try this one. Be aware it does not prevent against code pasted in your box.

Public Class Form1
    Private Sub TextBox1_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        If Not Char.IsDigit(CChar(e.KeyChar)) AndAlso Not {"."c, ","c, "-"c, ControlChars.Back}.Contains(e.KeyChar) Then
            e.Handled = True
        End If
    End Sub
End Class

Success
Cor


Wednesday, December 25, 2013 2:11 PM

Hello,

One nice thing about VB.NET is we have choices, uses events of a standard TextBox or create a custom one. In the custom one below only numerics are allowed (included pasting from Windows clipboard). In the Leave event we check to see if the value entered is in a specific range. There are two properties to set the range as shown below

<Category("Behavior"), _
Description("Minimum acceptable value")> _
Public Property MinValue As Integer
<Category("Behavior"), _
Description("Maximum acceptable value")> _
Public Property MaxValue As Integer

Then a read only property InRange to see if the value is okay. If not in range I have setup a ErrorProvider to inform the user there is an issue.

Usage

Public Class Form3
    Private Sub NumericTextbox1_Enter(sender As Object, e As EventArgs) Handles NumericTextbox1.Enter
        ErrorProvider1.SetError(NumericTextbox1, "")
    End Sub
    Private Sub NumericTextbox1_Leave(sender As Object, e As EventArgs) Handles NumericTextbox1.Leave
        If Not NumericTextbox1.InRange Then
            ErrorProvider1.SetError(NumericTextbox1, String.Format("Valid range is {0} to {1}", NumericTextbox1.MinValue, NumericTextbox1.MaxValue))
        End If
    End Sub
End Class

Control, add to project, compile, add an instance to your form and use the code above. Also add a ErrorProvider to the form.

Imports System.ComponentModel
''' <summary>
''' Allow only numerics
''' Only copy numerics from Windows clipboard
''' </summary>
''' <remarks>
''' The original developer is unknown.
''' Kevininstructor added min/max behavior
''' </remarks>
Public Class numericTextbox
    Inherits TextBox
    <Category("Behavior"), _
    Description("Minimum acceptable value")> _
    Public Property MinValue As Integer
    <Category("Behavior"), _
    Description("Maximum acceptable value")> _
    Public Property MaxValue As Integer
    <Category("Behavior"), _
    Description("Determine if value is in an acceptable range")> _
    Public ReadOnly Property InRange As Boolean
        Get
            If Not String.IsNullOrWhiteSpace(Me.Text) Then
                Return IsBetween(CInt(Text), MinValue, MaxValue)
            Else
                Return False
            End If
        End Get
    End Property

    Const WM_PASTE As Integer = &H302

    Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
        Dim Value As String = Me.Text
        Value = Value.Remove(Me.SelectionStart, Me.SelectionLength)
        Value = Value.Insert(Me.SelectionStart, e.KeyChar)
        e.Handled = CBool(Value.LastIndexOf("-") > 0) _
           Or Not (Char.IsControl(e.KeyChar) OrElse _
           Char.IsDigit(e.KeyChar) OrElse _
           (e.KeyChar = "."c And Not Me.Text.Contains(".") Or _
           e.KeyChar = "."c And _
           Me.SelectedText.Contains(".")) OrElse (e.KeyChar = "-"c And Me.SelectionStart = 0))
        MyBase.OnKeyPress(e)
    End Sub

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = WM_PASTE Then
            Dim Value As String = Me.Text
            Value = Value.Remove(Me.SelectionStart, Me.SelectionLength)
            Value = Value.Insert(Me.SelectionStart, Clipboard.GetText)
            Dim result As Decimal = 0
            If Not Decimal.TryParse(Value, result) Then
                Return
            End If
        End If
        MyBase.WndProc(m)
    End Sub
    Private Function IsBetween(ByRef sender As Integer, ByRef LowerLimit As Integer, ByRef UpperLimit As Integer) As Boolean
        If sender < LowerLimit Or sender > UpperLimit Then Return False
        Return True
    End Function

End Class

Screenshot

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.


Wednesday, December 25, 2013 4:06 PM

By the way, you can also use a MaskedTextBox control, with the Mask=”00”. You will only have to check that “MaskedTextBox1.Text = String.Empty OrElse CInt(MaskedTextBox1.Text) < 1 OrElse CInt(MaskedTextBox1.Text) > 12” is not true.


Wednesday, December 25, 2013 6:08 PM | 2 votes

You only need one line of code in the textbox's KeyPress event.  I added a second line to allow user to press the backspace key, and a third line for user to press the Enter key when done, so focus will go the the next control.

       If Not Char.IsDigit(e.KeyChar) Then e.Handled = True
        If e.KeyChar = Chr(8) Then e.Handled = False 'allow Backspace
        If e.KeyChar = Chr(13) Then TextBox2.Focus() 'Enter key moves to specified control

Solitaire


Thursday, December 26, 2013 8:54 AM | 1 vote

Hi Edward

You said "But if I may ask, is Exit Sub at the end of an If Statement the same as End If?"

No, the Exit Sub will exit right out of the sub routine. Exit For will exit out of a For . . . . To . . . Next. Exit Do will exit out of a Do  . . . . Loop.

There have been some good answers here.

Happy programming!

Leon C Stanley - - A dinky di VBer - - Code is like fresh baked bread - it goes stale after a while - - so why try to immortalize it ? and turn it into a Class? ^^ :-)


Monday, December 30, 2013 10:17 AM

Hey,

Thanks for all that, I appreciate.

But I found using the MaskedTextBox control much easier and easy to manage.


Monday, December 30, 2013 10:19 AM

Thanks mahn,

Atleast, from you, I've learnt something new.

Thanks and happy coding too.

Regards,

Edward Quixote.


Monday, December 30, 2013 10:38 AM

Hey,

Thanks for all that, I appreciate.

But I found using the MaskedTextBox control much easier and easy to manage.

Yea but don't ask then next time for a textbox but the problem you have to solve. 

Seems in fact you tell you don't want solutions anymore in future.

Success
Cor


Monday, December 30, 2013 10:45 AM

Leon,

Will you be so kind not to reply on follow up questions. This forum is not only for Edward but mainly a knowledge base for those searching for an answer. 

In this thread was great  information given. It is now damaged especially after that offending message from Edward to all other contributors who did there best to create in this thread some great code (not mine that was the most simple one just because I was afraid Edward would not even understand that part)

Success
Cor


Monday, December 30, 2013 11:58 AM

Hey,

You're way to handle this is so awesome.

It's easy to understand and manipulate and add other stuff too.

Thanks, other than the suggestion of using a ComboBox, I find your suggestion a better answer.

Thanks a lot, I appreciate.

Regards,

Edward Quixote.


Monday, December 30, 2013 12:55 PM

Hey Cor, I meant no offence. Didn't even knew it would be taken like an offensive statement. It was just a plain "THANKS". Like: Apart from learning about how to handle numerical values in a textbox, I also understood what Exit Sub means, and I appreciate that. Not that I don't appreciate the other contributions, I appreciate them too.


Saturday, April 12, 2014 6:31 PM

As kevin showed you have to account for 'Paste' if you use Key events.  I prefer simple,

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        Dim n As Integer
        If Not Integer.TryParse(TextBox1.Text, n) OrElse n < 1 OrElse n > 12 Then
            Debug.WriteLine("the textbox does not meet criteria")
        Else
            Debug.WriteLine("the textbox meets the criteria")
        End If
    End Sub

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics


Saturday, April 12, 2014 7:30 PM | 1 vote

You should consider using a NumericUpDown control, it can be given a minimum and maximum.


Saturday, April 12, 2014 7:49 PM

As kevin showed you have to account for 'Paste' if you use Key events.  I prefer simple,

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged        Dim n As Integer        If Not Integer.TryParse(TextBox1.Text, n) OrElse n < 1 OrElse n > 12 Then            Debug.WriteLine("the textbox does not meet criteria")        Else            Debug.WriteLine("the textbox meets the criteria")        End If    End Sub

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics

DB,

I agree with you, sort of.

I think using the .Validation event is more appropriate. Let them type the entire string and when the control loses focus, then check it.

As an example, this thread from a while back.

Please call me Frank :)


Saturday, April 12, 2014 11:13 PM

As kevin showed you have to account for 'Paste' if you use Key events.  I prefer simple,

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        Dim n As Integer
        If Not Integer.TryParse(TextBox1.Text, n) OrElse n < 1 OrElse n > 12 Then
            Debug.WriteLine("the textbox does not meet criteria")
        Else
            Debug.WriteLine("the textbox meets the criteria")
        End If
    End Sub

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics

DB,

I agree with you, sort of.

I think using the .Validation event is more appropriate. Let them type the entire string and when the control loses focus, then check it.

As an example, this thread from a while back.

Please call me Frank :)

I like to use ErrorProvider and the .TextChanged event, but to each his own.

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics


Saturday, April 12, 2014 11:15 PM

... and the .TextChanged event, but to each his own.

Try this then: Start your text as a period.

EDIT: Assuming the type is a double or decimal...