C# Troubleshooting the error provider -- validating text box data input - c#

everyone:
I'm trying to validate data in text boxes on a form. This is the code I have for my validator, but it's not working when I clearly violate the constraints set in the code (tabbing out of the txtbox, inputting less than 4 characters, etc. Any ideas of why this wouldn't work? The program runs, so it can't be syntax, so I suppose it must be logical error, but I just dont see it.
// Validation for Applicant Name text box
private void txtAppInfoName_Validating(object sender, CancelEventArgs e)
{
// Define what consitiutes a match
Match m = Regex.Match(txtAppInfoName.Text, #"\b[A-Za-z]\b");
if (m.Success == false)
{
errorProvider1.SetError(txtAppInfoName, "Please use only letters to type your name.");
txtAppInfoName.Select();
}
else if (txtAppInfoName.Text.Length < 4)
{
errorProvider1.SetError(txtAppInfoName, "Please type first and last names.");
txtAppInfoName.Select();
}
else if (txtAppInfoName.Text == "")
{
errorProvider1.SetError(txtAppInfoName, "Must enter a name.");
txtAppInfoName.Select();
}
else errorProvider1.SetError(txtAppInfoName, ""); // Remove the error provider
}

Most likely the handler is not even called at all. Make sure the handler txtAppInfoName_Validating is specified in the GUI designer under the Validating event.
If that doesn't work, try to add a breakpoint or throw an exception in the handler and see what happens.
If it stops, you can use the call-stack to inspect the error source.

Related

C# backspace on textbox creating errors immediately

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.
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.
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.

Clearing out a c# form text box

I am making a simple hangman style game in a C# form. I have it set as textBox1_TextChanged. Except everytime the user backspaces their guess letter it takes in blank space. How can I make it so after the message saying right/wrong it clears the space. I am getting annoyed at it telling the user they made a wrong guess after they backspace. This is my first post on this forum so sorry if the code text is weird. I just want the program to clear the text in the textBox after they guess.
UPDATE: Added suggested information. Now it does everything it is supposed to do. Except it pops up a windows saying " was found in the target word". This happens if guessLetter == null || guessLetter == correct || guessLetter == false.
private void textBox1_TextChanged(object sender, EventArgs e)
{
string guessLetter = textBox1.Text;
//textBox1.ReadOnly = true;
if (targetWord == null)
{
MessageBox.Show("Please start a new game.");
textBox1.Text = ("");
}
else
{
if (targetWord.Contains(guessLetter))
{
MessageBox.Show(guessLetter + " was found in the word");
}
else
{
MessageBox.Show(guessLetter + " was not found in the word");
incorrectGuessCtr++;
textBox3.Text = incorrectGuessCtr.ToString();
}
textBox1.Text = ("");
}
}
Don't only check if the targetWord is null, but also the guessLetter. You'd better use string.IsNullOrEmpty too, since it also checks if the string is empty:
if (!string.IsNullOrEmpty(targetWord) && !string.IsNullOrEmpty(guessLetter))
{
...
}
I guess you should also check if there is exactly one letter entered. That would mean this additional check:
if (guessLetter.Length == 1)
{
...
}
You will enter this event when you write code that changes Text property in textbox. I mean this.
textBox3.Text = incorrectGuessCtr.ToString();
Put something in function arguments or set some flags so that you can identify whether the event is called from user input or your clearing the text.
Just check how many times this function is called when user press backspace. You will get the idea.

Validation Logic

I am trying to create some validation for a form I have. There are two text boxes and two radio buttons on the form. My logic for this validation I know is a little rusty at the moment so any suggestions would be great.
Here is the code for what I have so far:
Keep in mind that the int errors is a public variable in the class
Start Button code:
private void btnStart_Click(object sender, EventArgs e)
{
errors = validateForm();
//Here I want the user to be able to fix any errors where I am little
stuck on that logic at the moment
//validate the form
while (errors > 0)
{
validateForm();
errors = validateForm();
}
}
ValidateForm Method:
private int validateForm()
{
errors = 0;
//check the form if there are any unentered values
if (txtDest.Text == "")
{
errors++;
}
if (txtExt.Text == "")
{
errors++;
}
if (validateRadioBtns() == true)
{
errors++;
}
return errors;
}
ValidateRadioBtns Method:
private Boolean validateRadioBtns()
{
//flag - false: selected, true: none selected
Boolean blnFlag = false;
//both of the radio buttons are unchecked
if (radAll.Checked == false && radOther.Checked == false)
{
blnFlag = true;
}
//check if there is a value entered in the text box if other is checked
else if(radOther.Checked == true && txtExt.Text == "")
{
blnFlag = true;
}
return blnFlag;
}
Overall I feel like this can somehow be more stream lined which I am fairly stuck on.
Any suggestions would be greatly appreciated since I know this is such a nooby question.
Well first since you have said that you want to validate for non-entered values, did you consider white spaces as an entry? since someone can just press space and then your validation would pass.
Aside from that, you might want to indicate which textbox they did not fill out or which group they did not click, it seems like you are using web forms so here is a walkthrough http://msdn.microsoft.com/en-us/library/vstudio/a0z2h4sw(v=vs.100).aspx.
If you are using windows forms you can use this walkthrough http://msdn.microsoft.com/en-us/library/ms229603(v=vs.110).aspx.
If you need to keep the existing logic, I would suggest extracting the repeating logic into separate functions and temporary btnFlag is not necessary also as you can return true and return false at the end.
private Boolean validateRadioBtns()
{
if (radAll.Checked == false && radOther.Checked == false)
return true;
else if(radOther.Checked == true && txtExt.Text.Trim().Length == 0 ) //just a quick sample of how you can trim the spaces and check for length
return true;
return false;
}
See the documentation for the validation patterns. You have chosen the explicit validation strategy, for which you would use the ContainerControl.ValidateChildren method and either perform your "Start" action or not.
Windows Forms has dedicated events for validation that allow you to react accordingly for each of your controls. You'll use Control.Validating and Control.Validated events.
So, unless ValidateChildren returns true, you don't need to initiate your "Start" action, i.e. the logic would become trivial.
P.S. you also probably don't need the errors variable as a class member since you return it from your validation function. For showing the error, prefer the "Tell, Don't Ask" idea by separating the error visualization in a separate component.

MessageBox Within A WinForms TextBox Validating Event Handler

I have a case where a textbox is validated to make sure it is not blank. However, there are some edge cases where the value should actually be blank. A Nullable<bool> blankText = null variable is set in the constructor. I'm using this code to validate and double check if the value is actually OK to be blank by confirming this with the user:
private void text_Validating(object sender, CancelEventArgs e)
{
if (string.IsNullOrWhiteSpace(text.Text))
{
do
{
if (blankText.HasValue && !blankText.Value)
{
errorProvider.SetError(text, "Blank or whitespace!");
e.Cancel = true;
break;
}
else if (blankText.HasValue && BlankText.Value)
{
errorProvider.SetError(text, "");
e.Cancel = false;
break;
}
else
{
DialogResult result = MessageBox.Show(this, "Field is blank, or contains only whitespace.\nAre you sure you want to use a blank/whitespace?", String.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
blankText = true;
else
blankText = false;
}
}
while (true);
}
else
{
e.Cancel = false;
errorProvider.SetError(text, "");
}
}
Even if the value for blankText = null it will still set the errorProvider error and fail validation. The MessageBox dialog is never displayed. I know that according to the documentation Microsoft states the following:
Do not attempt to set focus from within the Enter, GotFocus, Leave, LostFocus, Validating, or Validated event handlers. Doing so can cause your application or the operating system to stop responding. Source
Obviously when the MessageBox is displayed the control will implicitly lose focus...so maybe that's why this strange behavior is occurring. Can anyone confirm this? Any suggestions on a better way to handle this case?
In response to #adriano-repetti comment and some additional testing I removed the prompt from the validation event. The full solution I used was to create an additional property of bool? that can be checked if blank values are allowed, disallowed, or undefined. If either disallowed or undefined the validation fails if the value is blank. If the validation fails due to a blank value and the new IsBlankValueAllowed property a prompt is displayed to ask the user to confirm this behavior. I decided to use a Property instead of data within a Tag property since it felt less 'hacked'.

get and Set not working

I am writing the following get and set for validating an input from a Text Box. Basically it is supposed to check if the user has entered all of the values.
When I leave the TextBoxes empty , it does nothing and shows a '0' in output where that variable was being used. It does however show the system generated exception and stops the execution, but I wonder why doesn't it validate the input through the properties?
Here is my code:
public double RecoDoseSize
{
get
{
return recoDoseSize;
}
set
{
if (!(value>0))
{
MessageBox.Show("Please Enter the recommended dose size for this product");
textBox8.Focus();
}
recoDoseSize = value;
}
}
private void Submit2_Click(object sender, RoutedEventArgs e)
{
TotalContentProduct = double.Parse(textBox7.Text);
recoDoseSize = double.Parse(textBox8.Text);
NoOfDosespUnit = TotalContentProduct/recoDoseSize;
}
You are setting recoDoseSize, the backing field, not RecoDoseSize, the property which has your code in it. Thus, your code isn't executed. You need to change the second line of your method body to
RecoDoseSize = double.Parse(textBox8.Text);
(note the capital R).
Other have given the correct answer to the question as stated. Namely that you should call the uppercased RecoDoseSize if you want to use the getter/setter.
However it is extremely bad practice to show a message box inside the setter, because it violates the Principle of Least Surprise.
When someone looks at the line RecoDoseSize = double.Parse(textBox8.Text); it is not at all obvious that this operation could cause a message box to appear.
There are occasionally exceptions where it does make sense to have a setter trigger UI changes (for instance the Visible property on controls) however the default should always be to not do this unless you are sure it will be more confusing to not do so (for instance it would be surprising if you set Visible = false however it was still visible).
Regarding your comment on how you should implement it, the checking should be done in the click handler and the property can just be an auto-property, like so:
public double RecoDoseSize { get; set; }
private void Submit2_Click(object sender, RoutedEventArgs e)
{
TotalContentProduct = double.Parse(textBox7.Text);
double enteredSize;
if (!double.TryParse(textBox8.Text, out enteredSize) || enteredSize <= 0)
{
MessageBox.Show("Please Enter the recommended dose size for this product");
textBox8.Focus();
return;
}
RecoDoseSize = enteredSize;
NoOfDosespUnit = TotalContentProduct / recoDoseSize;
}
You'll want to use TryParse because with Parse you'll get an error if the text isn't a valid double. What TryParse does is return true or false depending on whether it succeeded, and it populates the out parameter with the result if it's successful.
So what this does is if it either failed to parse the result, or the result is <= 0 it shows the message box. In that case it also returns from the method so the rest of it isn't executed. Alternatively the rest of the method could be in an else block in which case the return isn't needed. It's a matter a style which way is preferred.
You're never actually using the getter/setter. You are using the actual field name: recoDoseSize directly. Change it to RecoDoseSize.
private void Submit2_Click(object sender, RoutedEventArgs e)
{
TotalContentProduct = double.Parse(textBox7.Text);
RecoDoseSize= double.Parse(textBox8.Text);
NoOfDosespUnit = TotalContentProduct/recoDoseSize;
}
You shouldn't be handling focus in your set statement.
Also, you need to make sure that value is not null, otherwise you can't compare it to anything (greater-than, etc.).

Categories