Clearing out a c# form text box - c#

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.

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 a TextBox leaves an invisible character

I'm developing a textbased RPG . If you type something into the textbox (tUser), the method Input() gets called and processes your query. If it matches a certain condition, something else, e. g. exiting the game, will happen.
public void Input()
{
if (tUser.Text.ToLower() == "ende" || listening)
{
if (tUser.Text.ToLower() == "ende")
{
if (MessageBox.Show(playername +
", wollt Ihr wirklich das Spiel ohne Speichern verlassen?", "Beenden",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
Application.Exit();
}
}
else
{
input = tUser.Text;
if (accept == 1 && !input.Any(char.IsDigit))
{
tRPG.AppendText("\nBitte gebt nur eine Zahl ein!");
}
else
{
listening = false;
}
}
}
// Reset
input = "";
tUser.Clear();
}
Your query will be submitted if you press Enter. After the process is done, the TextBox is being cleared.
If you try the same or any other command (again), nothing's going to happen, until you delete an "invisible" character in the TextBox.
I have also tried tUser.ClearUndo().
What is this character and how can I avoid it?
Why not just set the text to an empty string instead of using clear?
tUser.Text = string.Empty;
Well I believe it has something to do with the fact that your key events still set the value of the textbox or something alike after the textbox has been cleared. Anyway, a quick fix is to just use tUser.trimStart(' ') or something alike.
For some reason, the textbox keeps a carriage return. Adding e.Handled = true to the method which calls Input() solves this issue.
private void tUser_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
e.Handled = true;
Input();
}
}
e.Handled prevents the enter message from being processed after this handler has finished (source).

c# Make a variable value "" on button click, but only to the dialog box

I have a modeless UI that adds a userID to a list that allows or removes access to parts of a program. When I click the modify button everything works as it should. Suppose I close the dialog and realize "Wait, forgot to do X". When I reopen the dialog box, perform my work and click Modify, the value for adding the userID is still available to the program even though the textbox is blank.
It's happening somewhere in the following code.
public static void checkSame()
{
int count = 0;
bool test = false;
while (linesPerm.Length >= count && tbPermValue != "")
{
if (linesPerm.Length >= count)
{
test = linesPerm.Contains(tbPermValue);
count += (linesPerm.Length + 1);
if (test == true)
{
DialogResult dr = MessageBox.Show("The UserID " + tbPermValue +
" already exists in the Permissions column. "
+ Environment.NewLine + "Would you like to add the UserID" +
tbPermValue + " to the Permissions column anyway?",
"User Already Exists", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
switch (dr)
{
case DialogResult.Yes:
break;
case DialogResult.No:
tbPermValue = "";
break;
}
}
}
else
{
MessageBox.Show("Do Nothing");
}
}
}
If the user selects No on the dialog box, the value of tbPermValue is not available to the program. If the user selects Yes then the value of tbPermValue persists even if the dialog box is closed and reopened. I have tried to clear the textbox value like so.
tbUserName.Text = "";
tbUserName.Clear();
and several other ways. tbUserName value is being cleared from the textbox, but not from the code above. I get the value of tbPermValue like this.
public static void addPerm(System.Windows.Forms.Form targetForm)
{
foreach (Control C in targetForm.Controls)
{
if (C.GetType() == typeof(TextBox))
{
if (C.Text != "")
{
tbPermValue = C.Text;
}
}
}
}
This is a modeless dialog box owned by it's parent.
Can anyone point me in a direction that would remove access to tbPermValue to the DialogResult portion of the first code box after the button is clicked. I can't lose it completely because tbPermValue is used in other code down the line.
EDIT: Ok. I just tested this and the value is being held in memory. I have a dialog Form1 that has a button that opens dialog StartHere. On StartHere there is a button that opens Permissions. StartHere owns Permissions so that when I close StartHere, Permissions and all other child forms of StartHere will close. These are all modeless dialogs. My variable tbPermValue is being held in memory way back to Form1. The value is not being disposed when I close the dialog StartHere. I'm going to go back and research Garbage Collection at the advice of Eric below. Thank you Eric. I'll delete the question or at least post a new better question once I find out the rules for this process. Thank You.
Edit 2: Here is the code you asked for γηράσκωδ'αείπολλάδιδασκόμε
private void bModify_Click(object sender, EventArgs e)
{
WidgetLogic.addPerm(this);
WidgetLogic.checkSame();
WidgetLogic.writePerm(this);
WidgetLogic.writeAdmin(this);
WidgetLogic.writeDetailer(this);
tbUserName.Clear();
}
As noted above I have tried numerous ways to clear tbUserName to no avail.
Don't use tbPermValue but instead use the textbox directly:
while (linesPerm.Length >= count && tbUserName.Text != "")
EDIT
Change the code in addPerm to this, and you are done :):
public static void addPerm(System.Windows.Forms.Form targetForm)
{
foreach (Control C in targetForm.Controls)
{
if (C.GetType() == typeof(TextBox))
{
tbPermValue = C.Text;
}
}
}
You don't need the switch (dr) in checkSame()
I see that you say you have tried setting the following in the "yes" part of your switch statement:
tbUserName.Text = "";
tbUserName.Clear();
But in your "no" part, you don't set tbUserName, but instead you set the variable tbPermValue. From what I can tell, you should also be setting
tbPermValue = "";
in your "yes" part as well to clear that variable, or even just move it out of the switch and have it do that before the dialog closes since you would be setting it in all of the possible switch cases anyways.

C# skipping if not null

I have a click event handler which has to check if two text boxes are null or not, if both aren't the values are given to two variables and passed to another method.
One variable is a String, the other an integer. If the String is null but the integer isn't, it will work fine(Which it shouldn't!). But, if the integer is null and the String isn't, it will give me an error which is expected because it should not have reached that point.
Here's the code:
private void btnInsert_Click(object sender, EventArgs e)
{
String ActorName;
int Position;
if ((txtPosition.Text != null))
{
if ((txtActorName.Text != null))
{
ActorName = txtActorName.Text;
Position = int.Parse(txtPosition.Text);
InsertIntoArrayList(ActorName, Position);
PopulateActors();
}
else
{
MessageBox.Show("Please enter an Actor Name");
return;
}
}
else
{
MessageBox.Show("Please enter a position");
return;
}
}
As you can see, if txtPosition is not null, it then tests txtActorName. If either are null, it throws the relevant message. Assuming both are not null, it assigns the values to the variables and passes these to the InsertIntoArrayLIst method, followed by a call to the PopulateActors method.
If I enter an Actor name and a position, everything works fine. It's only if I don't enter a position that it somehow misses the fact that nothings entered, then slips up at the line Position = int.Parse(txtPosition.Text); because txtPosition is null.
Any help would be greatly appreciated!
Try using e.g. !string.IsNullOrEmpty(txtPosition.Text) instead of txtPosition.Text != null.
Alternatively, just use txtPosition.Text != "". After all, the Text property should never actually be null.
And of course, you should apply the same fix to both values, txtPosition and txtActor.
Don't confuse null and empty strings. They aren't the same thing.
The Text property of any control will only ever be null if you explicitly set it to null. In most cases you don't need to check this at all for that property; just comparing to an empty string is good enough
The String.IsNullOrEmpty() and String.IsNullOrWhitespace() methods are your friends.
There's no reason to nest the If blocks. Just use guard clauses to check one followed by the other for cleaner code:
.
private void btnInsert_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhitespace(txtPosition.Text))
{
MessageBox.Show("Please enter a position");
return;
}
if (string.IsNullOrWhitespace(txtActorName.Text))
{
MessageBox.Show("Please enter an Actor Name");
return;
}
int Position;
if (!int.TryParse(txtPosition.Text, out Position))
{
MessageBox.Show("Please enter a number in the position field");
return;
}
InsertIntoArrayList(txtActorName.Text, Position);
PopulateActors();
}
You could also use if (!string.IsNullOrWhiteSpace(txtPosition.Text) if you want to check for white spaces as well. Although performance wise it is a bit slower then using the standard string.IsNullOrEmtpy
if (txtPosition.Text != string.Empty) is another way to check.
Try This, it may resolve your Problem
ActorName = txtActorName.Text;
Position = int.Parse(txtPosition.Text=="" ? "0" : txtPosition.Text);

Simple C# direction with declaring variables

I just started trying to learn C#. I've read probably 50 tutorials so far and thought I had a good understanding. Apparently I was wrong. I've been doing a lot of reading on msdn.microsoft.com's C# Programmer's Reference but it's seeming to not be the best source for tutorials.
I'm literally trying to accomplish the most simplest of tasks. Trying to understand variables, manipulation, and inputs. I come from web programming and want to turn a PHP script into a desktop application so I'm trying to learn the basics of C# and I think I might need to learn a different language instead.
Basically, I have a textbox and a button. When the button is clicked, I want to check the text in the textbox and see if it matches a certain string. Then display a message box with a message.
private void btnClick_Click(object sender, EventArgs e) {
if(txtCL.Text == "one") {
bool myTest = true;
} else {
bool myTest = false;
}
if(myTest == true) {
MessageBox.Show("You entered the correct password.", "Important Message");
} else {
MessageBox.Show("The password you entered is not correct.", "Incorrect Input");
}
}
Would really appreciate if someone could point me to better tutorials so I can learn quicker. Microsoft's documentation really hasn't taught me anything really.
I apologize for the stupid question, feel free to call me an idiot.
It's a scoping issue, myTest does not exist, at least not down there - you're creating it each time within the scope of each of your initial conditions. If you do:
bool myTest = false;
if(txtCL.Text == "one") {
myTest = true;
}
if(myTest == true) {
MessageBox.Show("You entered the correct password.", "Important Message");
} else {
MessageBox.Show("The password you entered is not correct.", "Incorrect Input");
}
Then you're specifying your boolean value, and setting it to false (which is the default value for a bool anyway, actually), then checking if your condition is met and reassigning it accordingly; it can then be evaluated to show your message box.
You could shorten this code yet more, an exercise for the reader. (:
you don't really need a bool variable, you can make it simplier:
private void btnClick_Click(object sender, EventArgs e)
{
if(txtCL.Text == "one")
{
MessageBox.Show("You entered the correct password.", "Important Message");
}
else
{
MessageBox.Show("The password you entered is not correct.", "Incorrect Input");
}
}
and if you need some tutorials, just google "C# beginner tutorials" or if you prefer video tutorials, you can take a look here.
if(...) {
bool myTest = true;
} else {
bool myTest = false;
}
// At this point in time 'myTest' is not a known variable.
// It's out of scope already s your next line will cause a compile error.
if(myTest == true) {
...
}
So you need to declare the variable in scope
bool myTest = false;
if(...) {
myTest = true;
}
// Now you can use the myTest variable
if(myTest) {
...
}
As you already pointed out, you don't need the variable at all, since this would work all the same
private void btnClick_Click(object sender, EventArgs e) {
if(txtCL.Text == "one") {
MessageBox.Show("You entered the correct password.", "Important Message");
} else {
MessageBox.Show("The password you entered is not correct.", "Incorrect Input");
}
}
You can read as many books as you like, but since you already have programming experience with PHP I'd suggest to get more hands on experience with C#. In parallel a book of course does not hurt. But I think the approach you are following (reading online, coding stuff) will pay off in the end. Give it some time. Practice. A lot.
i am assuming that nothing is happening when you click the button. is this true? if it is, put a break point at the line: if(txtCL.Text == "one") , run the app and click it. If you do not hit the break point then there is no linkage between the 'click' event and your code. Explore the button properties and you will see a way to make the linkage.
stick with it, i was a PHP guy and now a C# guy. It can be done.

Categories