4

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.

J Young
  • 755
  • 1
  • 10
  • 26

5 Answers5

2

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);
  }
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
1

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.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
1

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.

Josh Earl
  • 18,151
  • 15
  • 62
  • 91
  • I would of used a time picker but from a design aspect the element did not fit at all. A dropdown list would work, but I have managed to implement suitable error checking for my text box. Thanks for your response, though! – J Young Mar 18 '12 at 03:35
1

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
   );
}
Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80
1

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;
    }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536