0

I am creating an event where if someone types into a text box it will show an error using this code:

try
{
    dblCostSqFt = double.Parse(txtCost.Text);
}
catch
{
    MessageBox.Show("Error. You must enter valid numbers. Please correct.");
    txtCost.Select();
    return;
}

The issue with this is if I input a backspace it will throw that error message immediately I would like to make it to where that doesn't happen.

Rufus L
  • 36,127
  • 5
  • 30
  • 43
Jem
  • 45
  • 1
  • 6
  • 1
    I imagine you probably have a method assigned for validating text that is linked to your textbox textchanged event, so any time the text changes at all (including backspace) it checks for valid input, and if it isn't valid it throws the error. – emsimpson92 Nov 09 '18 at 21:34
  • 4
    Critical info missing. Which event handler contains the code posted? – Steve Nov 09 '18 at 21:37
  • 1
    Use TryParse instead. – LarsTech Nov 09 '18 at 21:37
  • What I am getting from your code is that you are not handling the validations in the manner it should be. Throwing exceptions in such a case is not a good idea. You should probably just get the value of the text box on change, and after that validate that value using maybe Regex patterns or any other possible validations. If that is invalid, then maybe you can throw an error. You can also skip validation and directly try to parse the value. If the parse is successful, cool. If not, throw error/exception. – Shahzad Nov 09 '18 at 21:40
  • I'll re-post all I got to make this easier sorry about that. – Jem Nov 09 '18 at 21:42
  • 1
    Maybe first check whether there is text in that textbox and ignore (without message) if it is empty – Hans Kesting Nov 09 '18 at 21:43
  • 1
    Note that you can edit your question – Hans Kesting Nov 09 '18 at 21:44
  • Two things you should add to your post. 1) What environment you are writing for (WPF, WinForms, something else), and 2) what event you are handling. If you had included the name of the event handler function, we probably could have figured that out, but it's not there – Flydog57 Nov 09 '18 at 21:56
  • Possible duplicate of [Parse v. TryParse](https://stackoverflow.com/questions/467613/parse-v-tryparse) – mjwills Nov 09 '18 at 22:01
  • 5
    I'll let the other contributors address your validation logic. I'll just chime in to say: **please do not display a modal dialog *while a user is editing a field***. That's one of the most user-hostile things you can do as a UX developer. Better to display an inline error indicator, or at minimum wait until they've finished typing (e.g., focus has left the text box, or some sort of 'commit' action is taken). – Mike Strobel Nov 09 '18 at 22:02
  • Just a hint: If you are trying to limit user to numeric input then this is not the right way to do it. Instead try sth like this: https://stackoverflow.com/questions/463299/how-do-i-make-a-textbox-that-only-accepts-numbers – roozbeh S Nov 09 '18 at 22:17

2 Answers2

1

You're working with userinput here. Therefore i'd suggest to use Double.TryParse()

  • If you've got a string, and you expect it to always be a double (say, if some web service is handing you a double in string format), you'd use Double.Parse().

  • If you're collecting input from a user, you'd generally use Double.TryParse(), since it allows you more fine-grained control over the situation when the user enters invalid input.

With tryparse() your code will be something like this:

if (!double.TryParse(txtCost.Text, out var dblCostSqFt))
{
    MessageBox.Show("Error. You must enter valid numbers. Please correct.");
    txtExample.Select(0, txtCost.Text.Length);
    return;
}

To make the example complete and address the issue one could simply check if the Text is not null or empty by using String.IsNullOrEmpty() making the whole code:

// makes sure your app isn't crashing upon backspaces.
if(string.IsNullOrEmpty(textCost.Text))
{
    // Personally i'd indicate the user nothing is typed in (yet).
    return;
}
if (!double.TryParse(txtCost.Text, out var dblCostSqFt))
{
    // The user filled in something that can't be parse to doubles.
    MessageBox.Show("Error. You must enter valid numbers. Please correct.");
    txtExample.Select(0, txtCost.Text.Length);
    return;
}
// All is great; Do stuff with dblCostSqFt.
Baklap4
  • 3,914
  • 2
  • 29
  • 56
  • 1
    You don't need to initialize `dblCostSqFt`, you set it in the next line. And, if you are using a recent version of the C# compiler, you could have simply said: `if (!double.TryParse(txtCost.Text, out var dblCostSqFt))`, declaring the variable inline. – Flydog57 Nov 09 '18 at 21:58
  • 1
    While this is good advice, it doesn't address the question of how to avoid showing the error when the backspace key is pressed. – Rufus L Nov 09 '18 at 22:05
  • Neither did OP show us how he currently has implemented key listeners. With a dependency of that there's only a posibility to check if the text is null or empty and if it is return. Making the app not crash – Baklap4 Nov 09 '18 at 22:21
0

Assuming you are using WPF for your UI without straying too far from what you have I would use something like below (as LarsTech suggested, use TryParse to test if the value can be converted). Note the if block surrounding the core code within the function, you can avoid execution entering the if block by checking if the key pressed was backspace. I also added a check for the enter key as many users would press the enter key to close the MessageBox, which would cause the event to trigger once again.

private void txtExample_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Back && e.Key != Key.Enter)
    {
        double dblCostSqFt = 0;

        if (!double.TryParse(txtExample.Text, out dblCostSqFt))
        {
            MessageBox.Show("Error. You must enter valid numbers. Please correct.");
            txtExample.Select(0, txtExample.Text.Length);
        }
    }
}

Never rely on exception handling to control the workflow of your application, exceptions have a ton of overhead and it is typically a bad practice in general.

You can accomplish the same thing in WinForms as well using the following...

private void txtExample_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode != Keys.Back && e.KeyCode != Keys.Enter)
    {
        double dblCostSqFt = 0;

        if (!double.TryParse(txtExample.Text, out dblCostSqFt))
        {
            MessageBox.Show("Error. You must enter valid numbers. Please correct.");
            txtExample.Select();
        }
    }
}

It looks like you are using WinForms because your textbox.Select function call does not supply any arguments, only WinForms supports an overload of the select function without any arguments.

Nick Hanshaw
  • 376
  • 4
  • 7