views:

6416

answers:

7

I'm using the following code to validate the text entered by user. It works perfectly fine. But I want to add the backspace feature so as to allow the user to delete the wrongly entered number.

I have tried a couple of things and they worked but before last digit (after the decimal point) i.e. it does not allows to delete after the number has been completely entered. number is being entered in the format: 12313213.45

What shall I do?

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

    'validation '
    Dim KeyAscii As Short = Asc(e.KeyChar)
    If Not ((KeyAscii >= System.Windows.Forms.Keys.D0 And KeyAscii <= System.Windows.Forms.Keys.D9) Or (KeyAscii = System.Windows.Forms.Keys.Back) Or Chr(KeyAscii) = "." Or (Chr(KeyAscii) Like "[ ]")) Then
        KeyAscii = 0
        TextBox5.Focus()
    End If
    If KeyAscii = 0 Then
        e.Handled = True
    End If

    If TextBox5.Text.IndexOf(".") >= 0 And e.KeyChar = "." Then
        e.Handled = True
    End If

    If TextBox5.Text.IndexOf(".") > 0 Then
        If TextBox5.SelectionStart > TextBox5.Text.IndexOf(".") Then
            If TextBox5.Text.Length - TextBox5.Text.IndexOf(".") = 3 Then
                e.Handled = True
            End If
        End If
    End If
End Sub
+2  A: 

There is a much easier way to validate this. Try convert the text in the edit box to a floating point number. If you catch an exception, the number is not valid.

Trying to validate keystroke by keystroke is going to cause you many headaches.

Bork Blatt
Is it wise to use exceptions to perform a task?
dmce
No, which is why you use `Decimal.TryParse` instead.
Pavel Minaev
A: 

Don't try and validate keystrokes one at a time.
1) You have just found that backspace requires more code, now add support for cut/copy and paste, and the delete key and typing replaces selection. The code is not nice.
2) It will only confuse the user. Or worse, they try and type a . seperated date into your field, you force that date into a legitimate number by ignoring the second . and they have now entered something totally wrong and your program won't tell them.
The validating event of the textbox is where this sort of logic should go. It will fire when the focus moves to another control (whose CausesValidation property is true, this allows cancel buttons to be clicked even if the current control is not in a valid state).
In the validating event you can do all the checks you need to and cancel the event if the data is not valid, as well as displaying whatever message you need to. To validate the value I would suggest Single.TryParse to start with, then if the conversion succeeds you can continue to do any range checks that you require. TryParse is better than @Bork's suggestion because it is easier to read and avoids the throwing/catching of un-necessary exceptions.

EDIT: Just noticed you are also restricting the length of the entered text. You can do that by setting the MaxLength property of the TextBox.

pipTheGeek
+1  A: 

An even better way is to use a control that supports decimals (if that is you're using something like infragistics, componentone, devexpress, etc.) The user gets visual cues and can do neat things like click the arrows to advance the numbers.

If you're using plain old winforms, have a look at the masked edit control.

Personally I find it HUGELY irritating when applications try to correct me and i'm not done entering data. It's much more user friendly to let the user finish and then notify them if there are any problems.

Conrad
Actually, the stock `NumericUpDown` WinForms control can handle decimal fractions - but it requires you to specify how many decimal places to show, and won't let user input more than that.
Pavel Minaev
A: 

I think the link below should give you exactly what you're after:

Numeric TextBox

Although it requires a fair amount of code to handle validation on each keypress, it's certainly possible, and the code above seems to handle delete, backspace, copy/pasting etc.

CraigTP
A: 

Or use a regular expression for the tough stuff

A: 

Yeah, or just make that nested if...then block look like this:

If Textbox5.Text.IndexOf(".") > 0 Then
    If Textbox5.SelectionStart > Textbox5.Text.IndexOf(".") Then
        If Textbox5.Text.Length - Textbox5.Text.IndexOf(".") = 3 Then
            If KeyAscii <> System.Windows.Forms.Keys.Back Then e.Handled = True
        End If
    End If
End If
Jeff
A: 

txtMobil.Text = Format(txtMobil.Text, "###-###-####")

Manu Manoharan