J Young
J Young

Reputation: 755

C# - Correct validation for integers

I am currently building my project using windows forms and came across a minor "problem".

I have the user enter an hour which is stored as an int. I want to provide detailed feedback to the user so that they know exactly what they have done wrong should they cause an error.

If no value is given, a format exception is thrown. If anything but an integer is given, a format exception is thrown.

This means I cannot directly tell the user that the new item could not be added due to EITHER 1) no value or 2) not an integer as they both use the same exception.

How can I solve this and what would be the best solution?

Many thanks.

Upvotes: 4

Views: 291

Answers (5)

Hans Passant
Hans Passant

Reputation: 941277

This is well supported in Winforms. Use the Validating event to check the entry, the ErrorProvider component to report the error. A sample event handler:

    private void textBox1_Validating(object sender, CancelEventArgs e) {
        int hour;
        e.Cancel = true;
        if (textBox1.Text.Length == 0) errorProvider1.SetError(textBox1, "Can't be empty");
        else if (!int.TryParse(textBox1.Text, out hour)) errorProvider1.SetError(textBox1, "Not a number");
        else if (hour < 1) errorProvider1.SetError(textBox1, "Hour too small");
        else if (hour > 24) errorProvider1.SetError(textBox1, "Hour too large");
        else {
            e.Cancel = false;
            errorProvider1.SetError(textBox1, "");
        }
    }

Then you just need to check if all entries were satisfactory. Use the ValidateChildren() method in the dialog's OK button click event handler:

    private void OKButton_Click(object sender, EventArgs e) {
        if (ValidateChildren()) this.DialogResult = DialogResult.OK;
    }

Upvotes: 1

Dave Cousineau
Dave Cousineau

Reputation: 13148

some example code related to your question; note ValidateData in particular:

// called from ok button click or similar event
private void Accept()
{
   if (!ValidateData())
      return;

   SaveData();
   DialogResult = DialogResult.Ok;
   Dispose();
}

private bool ValidateData()
{
   int val;

   if (string.IsNullOrEmpty(mTextBox.Text))
      return FailValidation("Value can not be empty.", mTextBox);

   if (!int.TryParse(mTextBox.Text, out val))
       return FailValidation("Value was not an integer.", mTextBox);

   return true;
}

// do something with the value if you need
private void SaveData()
{       
}

// post a message to the user, and highlight the problematic control
// always evaluates to false
private bool FailValidation(string pMessage, Control pControl)
{
     if (pControl != null)
     {
        pControl.Focus();
        TextBox textBox = pControl as TextBox;
        if (textBox != null)
           textBox.SelectAll();
     }

     AlertBox(pMessage);
     return false;
}

// quick alert message method
private void AlertBox(string pMessage)
{
   return MessageBox.Show
   (
      pMessage,          
      Application.ProductName,
      MessageBoxButtons.OK,
      MessageBoxIcon.Exclamation,
      MessageBoxDefaultButton.Button1
   );
}

Upvotes: 1

Josh Earl
Josh Earl

Reputation: 18351

If I can suggest a possible alternate solution... The best validation is preventing the bad input in the first place. Can you restrict the values the user can choose by using a control like a time picker or dropdown list? A dropdown list would still be keyboard friendly for powerusers, and it is a little easier for those who prefer a mouse. Wins for everyone.

Upvotes: 1

Alexei Levenkov
Alexei Levenkov

Reputation: 100527

Use int.TryParse to check format and than in success case check if integer is in valid range. Use String.IsNulOrEmpty to check for empty string.

Upvotes: 1

Mitch Wheat
Mitch Wheat

Reputation: 300509

Use the Int32.TryParse Method and check return value. You can simply check for no value entered before calling TryParse.

Here's an example of usage from MSDN:

  int number;
  bool result = Int32.TryParse(value, out number);
  if (result)
  {
     Console.WriteLine("Converted '{0}' to {1}.", value, number);         
  }
  else
  {
     if (value == null) value = ""; 
     Console.WriteLine("Attempted conversion of '{0}' failed.", value);
  }

Upvotes: 2

Related Questions