Search code examples
c#parsingwindows-forms-designer

C# 'live' parsing of input from TextBox


I have following problem. I use Windows Forms for simple calculations, and want that the app will calculate the values live based on the input provided into text box. So even if my desired input in the TextBox is 3-digit number, it will calculate the results even for the first digit. Even triggering the calculations is TextBoxChanged.

The problem is when I try to provide negative number.

so here is the code, I provide some value into TextBox called dim1:

private void dim1_TextChanged(object sender, EventArgs e)
        {
            if (checkInput(dim1))
            {
                RunClac();
            }
        }

Checking input:

public const NumberStyles numstyle = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowExponent | NumberStyles.AllowLeadingWhite | NumberStyles.AllowLeadingWhite;

        public bool checkInput(TextBox tb)
        {
            // bool check = Double.TryParse(tb.Text, out val);
            bool check = double.TryParse(tb.Text,numstyle,null, out double val);
                if (!(tb.Text == "") && check)
                {
                    return true;
                }
                else //(tb.Text == "")
                {
                    tb.Text = "1";
                    tb.SelectAll();
                    return false;
                }
        }

Once input is checked RunCalc goes as this:

public void RunClac()
{
double bplate = double.Parse(dim1.Text);
...
}

The problem is that TryParse do not allow to have negative number as the first character from the string. Even if I change the InputCheck as shown below (or instead of and in first if) the program crasahes on parsing anyway.

public const NumberStyles numstyle = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowExponent | NumberStyles.AllowLeadingWhite | NumberStyles.AllowLeadingWhite;

        public bool checkInput(TextBox tb)
        {
            // bool check = Double.TryParse(tb.Text, out val);
            bool check = double.TryParse(tb.Text,numstyle,null, out double val);
                if (!(tb.Text == "") **|** check)
                {
                    return true;
                }
                else //(tb.Text == "")
                {
                    tb.Text = "1";
                    tb.SelectAll();
                    return false;
                }
        }

What is the best solution for it?


Solution

  • The main problem is this code:

    tb.Text = "1";
    tb.SelectAll();
    

    If I understand the code correctly this should immediately replace - with a 1, thus preventing negative numbers from being entered.

    You could perhaps add a special check for this, something like

    else if(tb.Text.Trim() = '-'){
      return false;
    }
    

    But my recommendation would be some other way to inform the user that the number is invalid, for example:

    if(double.TryParse(tb.Text, out var value)){
       tbBorder.Color = Colors.Transparent;
       RunClac(value);
    }
    else{
       tbBorder.Color = Colors.Red;
    }
    

    This way the users text is never replaced. So if the user pastes "123abc" he can just edit the text. See also ErrorProviders for a more systematic way to inform the users of input errors.