C# backspace on textbox creating errors immediately - c#

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.

Related

Execute specific blocks of code based on which key on the keyboard is pressed

I am very new to the programming world and recently dove into c#. I don't want to waste your time so I'll get right to it. I wanted to create a program just to test my knowledge, and thought I could attempt to execute specific blocks of code based on which key on the keyboard is pressed by the user. I tried doing this by creating an event handler that contained if statements, but then realized I didn't know how to have the event handler active in the program.
For example, and as you can see in the below snippet, after the WriteLine in Line 5 lets say I wanted to raise the EventKeyPress event so that it waits for user input and reads the key they have pressed and reacts accordingly, how would I do that?
Again, I'm almost a complete beginner and have searched around for explanations about event handlers for hours and still can't wrap my head around what I am supposed to do or if I am even using the event handler correctly. Thanks in advance!
static void Main();
{
if (search == "Ball")
{
Console.WriteLine("Press enter to exit or backspace to return to the search bar")
// RIGHT HERE
}
else
{
Console.WriteLine("Sorry, I don't recognize {0}", search);
}
void EventKeyPress(object sender, KeyPressEventArgs e)
{
for (int i = 0; i < 1;)
{
if (e.KeyChar == (char)Keys.Enter)
{
// exit app
}
else if (e.KeyChar == (char)Keys.Back)
{
// go back to search
}
else
{
i = 0; // error
}
}
}
}
So, you're asking for something that involves Threading which is not a beginner thing to accomplish at all. The best way to do this for a beginner is to ask for a prompt, then accept as an input. For example.
Console.WriteLine("Hello, what's your name?");
string nameStr = Console.ReadLine();
Console.WriteLine($"Hello, {nameStr}");
You can then use your variable and apply it to an if/while or whatever kind of conditional.
if (nameStr == "Matt"){
//Do This Code.
}
Once you have that code, add a sequential method that will ask the user to return to the main menu or whatever you want it to do.
Main.ReturnMenu(); //Or whatever you want to use.

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.

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

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.

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