Why is a variable not recognized in an event handler? - c#

I have two issues with this piece of code. I 'm having trouble because the submit button event doesn't recognize the variable calculated in the text box event, and because the text box event isn't recognizing my if statements as statements. You can see where I'm having trouble in the comments below.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication11
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
int points;
int userInput = int.Parse(textBox1.Text);
if (userInput == 0)
{
points == 5; //I CANNOT COMPILE BECAUSE APPARENTLY I AM NOT ALLOWED TO USE
THIS AS A STATEMENT?
}
if (userInput == 1)
{
points == 10;
}
if (userInput == 2)
{
points == 20;
}
if (userInput ==3)
{
points == 30;
}
else
{
points == 40;
}
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show = ("You have been awarded" + textBox1.points + "points");
} //I WANT TO BE ABLE TO RETRIEVE THE POINTS CALCULATED USING THE CALCULATION IN
TEXT BOX, BUT I CANNOT COMPILE THE BUTTON EVENT DOES NOT RECOGNIZE THE POINTS
VARIABLE
private void label1_Click(object sender, EventArgs e)
{
}
}
}

The == symbol is a comparison symbol not an assignment symbol
You need to use
if (userInput == 2) // this is a comparison
{
points = 20; // this is an assignment
}

First you have declared points local to the TextChanged event, so it won't be accessible in your button click event.
textBox1.points is not right since int points declaration has nothing to do with the TextBox, you may declare points as a class variable, something like
public partial class Form1 : Form
{
int points =0;
public Form1()
{
InitializeComponent();
}
//......//
this would then work out as
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show( string.Format("You have been awarded {0} points",this.points));
}
Also you do assignment using = sign, so points = 5; would be the right thing to do

To add value to variable you should write:
points = 5;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication11
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public int points=0;
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
int userInput = int.Parse(textBox1.Text);
if (userInput == 0)
{
points = 5;
}
if (userInput == 1)
{
points = 10;
}
if (userInput == 2)
{
points = 20;
}
if (userInput ==3)
{
points = 30;
}
else
{
points = 40;
}
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show = ("You have been awarded" + points.ToString() + "points");
}
private void label1_Click(object sender, EventArgs e)
{
}
}
}

As already stated - you confussed with assignment operator and with global/local variables.
But there is several other "errors" in your code. User input might be simple text - so there will be exception, you should use int.TryParse instead of int.Parse. Also there are plenty of ifs in your code - but they cannot fire all together, I recomend use switch. And of course you should try to name your constants somehow, it will make your code much more readable!
Overral your code might look like this:
int pointsAvarded = 0;
private void textBox1_TextChanged(object sender, EventArgs e)
{
pointsAvarded = 0; //so you can be sure to use the latest input
int userInput = 0;
if (int.TryParse(textBox1.Text, out userInput))
switch (userInput)
{
case 0:
points = 5;
break;
case 1:
points = 10;
break;
...
default:
points = 40;
break;
}
}
private void button1_Click(object sender, EventArgs e)
{
if (pointsAvarded != 0)
MessageBox.Show("You have been awarded" + pointsAvarded + "points");
}

Related

Passing data between form1 and form2 in C# [duplicate]

This question already has answers here:
How do you pass an object from form1 to form2 and back to form1?
(4 answers)
Closed 5 years ago.
I'm supposed to make a math practice program for kids. They should be able to choose 1 operation and the amount of digits (1, 2 or 3 digit) the numbers will have. It then has to out put 10 random questions according to the selection made by the kid, then once they have completed the quiz, it should display their results and which questions they got wrong.
I have two selections being made on form1, operations and # of digits, which are assigned numbers (1. (*) 2. (/) 3. (+) 4. (-)). All i need to do is communicate the operation number and # of digits to form2, where the questions will be generated and displayed.
Here's my code for form1 so far:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinalProject
{
public partial class Form1 : Form
{
public static int operation = 0;
public static int digits = 0;
public Form1()
{
InitializeComponent();
}
// this is to make sure only one box is checked for both selections. Starts here
private void label1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void MulCB_CheckedChanged(object sender, EventArgs e)
{
if ( MulCB.Checked == true)
{
operation = 1;
DivCB.Checked = false;
AddCB.Checked = false;
SubCB.Checked = false;
}
}
private void DivCB_CheckedChanged(object sender, EventArgs e)
{
if (DivCB.Checked == true)
{
operation = 2;
MulCB.Checked = false;
AddCB.Checked = false;
SubCB.Checked = false;
}
}
private void AddCB_CheckedChanged(object sender, EventArgs e)
{
if (AddCB.Checked == true)
{
operation = 3;
DivCB.Checked = false;
SubCB.Checked = false;
MulCB.Checked = false;
}
}
private void SubCB_CheckedChanged(object sender, EventArgs e)
{
if (SubCB.Checked == true)
{
operation = 4;
DivCB.Checked = false;
AddCB.Checked = false;
MulCB.Checked = false;
}
}
private void oneDCB_CheckedChanged(object sender, EventArgs e)
{
if(oneDCB.Checked == true)
{
digits = 1;
twoDCB.Checked = false;
threeDCB.Checked = false;
}
}
private void twoDCB_CheckedChanged(object sender, EventArgs e)
{
if ( twoDCB.Checked == true)
{
digits = 2;
oneDCB.Checked = false;
threeDCB.Checked = false;
}
}
private void threeDCB_CheckedChanged(object sender, EventArgs e)
{
if (threeDCB.Checked == true)
{
digits = 3;
oneDCB.Checked = false;
twoDCB.Checked = false;
}
}
private void button8_Click(object sender, EventArgs e)
{
// operations: 1. (*) 2. (/) 3. (+) 4. (-)
// digits are as number indicates.
// Second window popup.
Form2 settingsForm = new Form2();
settingsForm.Show();
}
}
}
Here's form2, naked pretty much.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinalProject
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void FinishedBtn_Click(object sender, EventArgs e)
{
}
}
}
This might work.
There are comments in the code.
The workflow is creating a new instance of the class Form2 and setting two public variables. Public means that they can be accessed from outside of the class (see here, if you want). Then the method Show() is called and the Form appears. In the Form2 code, the public variables now have the values previously specified and can be used.
Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinalProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// this is to make sure only one box is checked for both selections. Starts here
private void label1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void MulCB_CheckedChanged(object sender, EventArgs e)
{
if ( MulCB.Checked == true)
{
operation = 1;
DivCB.Checked = false;
AddCB.Checked = false;
SubCB.Checked = false;
}
}
private void DivCB_CheckedChanged(object sender, EventArgs e)
{
if (DivCB.Checked == true)
{
operation = 2;
MulCB.Checked = false;
AddCB.Checked = false;
SubCB.Checked = false;
}
}
private void AddCB_CheckedChanged(object sender, EventArgs e)
{
if (AddCB.Checked == true)
{
operation = 3;
DivCB.Checked = false;
SubCB.Checked = false;
MulCB.Checked = false;
}
}
private void SubCB_CheckedChanged(object sender, EventArgs e)
{
if (SubCB.Checked == true)
{
operation = 4;
DivCB.Checked = false;
AddCB.Checked = false;
MulCB.Checked = false;
}
}
private void oneDCB_CheckedChanged(object sender, EventArgs e)
{
if(oneDCB.Checked == true)
{
digits = 1;
twoDCB.Checked = false;
threeDCB.Checked = false;
}
}
private void twoDCB_CheckedChanged(object sender, EventArgs e)
{
if ( twoDCB.Checked == true)
{
digits = 2;
oneDCB.Checked = false;
threeDCB.Checked = false;
}
}
private void threeDCB_CheckedChanged(object sender, EventArgs e)
{
if (threeDCB.Checked == true)
{
digits = 3;
oneDCB.Checked = false;
twoDCB.Checked = false;
}
}
private void button8_Click(object sender, EventArgs e)
{
// operations: 1. (*) 2. (/) 3. (+) 4. (-)
// digits are as number indicates.
// Second window popup.
// it's the question form, right?
Form2 questionForm = new Form2();
//"Write" your settings in the other form's variables
//You will have to write code that finds out which checkbox is which number! For now its fixed.
questionForm.operation = 2;
questionForm.digits = 1;
questionForm.Show();
//Hide Form1
this.Hide();
}
}
}
Form2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinalProject
{
public partial class Form2 : Form
{
public static int operation;
public static int digits;
public Form2()
{
InitializeComponent();
}
//do NOT paste this. It can be added by creating an event handler
// you also might not need this, but this method is called when this Form appears. It's an example.
// https://msdn.microsoft.com/en-us/library/zwwsdtbk(v=vs.80).aspx
private void Form2_Load(object sender, EventArgs e)
{
//here you can use your variables for example (also anywhere within this class!)
//e.g.
Textbox1.Text = (string)operation;
}
private void FinishedBtn_Click(object sender, EventArgs e)
{
}
}
}

Trouble with random number guessing game in c#

So I am working on a project for school that in a guessing game for a randomly generated number between 1-100. The only trouble I am having at the moment is that every time the user enters a new number the generated number also changes. I tried putting the code to generate the number in the form loader but then I can't access it later in the program. Here's what I have so far.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void guessButton_Click(object sender, EventArgs e)
{
int userGuess;
userGuess = int.Parse(guessText.Text);
Random rand = new Random();
int number = rand.Next(1, 100);
label2.Text = "" + number;
if (userGuess > number)
{
resultLabel.Text = "Your guess is too high";
}
else if (userGuess < number)
{
resultLabel.Text = "Your guess is too low.";
}
else if (userGuess == number)
{
resultLabel.Text = "That is correct!";
}
guessText.Clear();
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
As it currently stands, the Random number is overwritten every time the guessButton_Click function is run.
You are declaring Random inside the guessButton_Click function, that is called every time the guess button is clicked (that's also a memory leak!).
To fix, declare it as a global variable, in the namespace:
Edit: The below code compiles properly, and works perfectly.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
int number = new Random().Next(1, 100);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void guessButton_Click(object sender, EventArgs e)
{
int userGuess;
userGuess = int.Parse(guessText.Text);
label2.Text = "" + number;
if (userGuess > number)
{
resultLabel.Text = "Your guess is too high";
}
else if (userGuess < number)
{
resultLabel.Text = "Your guess is too low.";
}
else if (userGuess == number)
{
resultLabel.Text = "That is correct!";
}
guessText.Clear();
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
You are getting a new random number every button click try the following:
public partial class Form1 : Form
{
Random rand;
int number;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
rand = new Random();
number = rand.Next(1, 100);
}
private void guessButton_Click(object sender, EventArgs e)
{
int userGuess;
userGuess = int.Parse(guessText.Text);
label2.Text = "" + number;
if (userGuess > number)
{
resultLabel.Text = "Your guess is too high";
}
else if (userGuess < number)
{
resultLabel.Text = "Your guess is too low.";
}
else if (userGuess == number)
{
resultLabel.Text = "That is correct!";
}
guessText.Clear();
}
}

Catch exception and reset windows form C#

I'm currently working on my first assignment using windows forms in visual studio and have been a little stuck.
I'm trying to test if a user input is numeric, and if the input is not numeric, a little message box pops up and alerts the user. (I've done this part). The issue I'm having is the and error continues to pop in visual studio
Is this a formatting issue? Should I reformat my code? As you can probably see I am new the C# (and programming).
My code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace wtgCalculator {
public partial class Form1 : Form {
const double maleratio = 0.536;
const double femaleratio = 0.492;
public Form1() {
InitializeComponent();
}
private void textBox1_TextChanged(object sender, EventArgs e) {
}
private void Form1_Load(object sender, EventArgs e) {
}
private void label1_Click(object sender, EventArgs e) {
}
private void textBox1_TextChanged_1(object sender, EventArgs e) {
}
private void WaistNumericCheck() {
double waist;
string inpwaist = heighttextbox.Text;
if (double.TryParse(inpwaist, out waist)) {
MessageBox.Show("Value must be numeric"); //this is where the problem is
}
}
private void HeightNumericCheck() {
//todo
}
private void button1_Click(object sender, EventArgs e) {
//record inputs to variables
WaistNumericCheck();
HeightNumericCheck();
double height = double.Parse(heighttextbox.Text);
double waist = double.Parse(waisttextbox.Text);
//check is inputs are within boundry
CheckDimensions(height, waist);
//test
// ShowResult(height, waist);
}
private void CheckLimits(double height, double waist) {
double result = CalculateRatio(height, waist);
if (Female.Checked) {
if (result < femaleratio) {
MessageBox.Show("Your risk of obesity related cardiovasular is low");
}
if (result > femaleratio) {
MessageBox.Show("Your risk of obesity related to cardiovascular is high");
}
}
if (Male.Checked) {
if (result < maleratio) {
MessageBox.Show("Your risk of obesity related cardiovasular is low");
}
if (result > maleratio) {
MessageBox.Show("Your risk of obesity related cardiovasular is High");
}
}
//testing
MessageBox.Show(result.ToString());
}
private void ShowResult(double height, double waist) {
//double result = CalculateRatio(height, waist);
//if (Female.Checked) {
// if (result < femaleratio) {
// MessageBox.Show("Your risk of obesity related cardiovasular is low");
// }
// if (result > femaleratio) {
// MessageBox.Show("Your risk of obesity related to cardiovascular is high");
// }
//}
//if (Male.Checked) {
//}
}
private static void CheckDimensions(double height, double waist) {
if (height <= 120) {
MessageBox.Show("Height must be greater than 120cm");
}
if (waist <= 60) {
MessageBox.Show("Waist must be greater than 60cm");
}
}
private void Gender_CheckedChanged(object sender, EventArgs e) {
button1.Enabled = true;
}
private static double CalculateRatio(double height, double waist) {
double finalratio = waist / height;
return finalratio;
}
}
}
Thanks again, and let me know if more information is required.
You're not really handling this correctly. .Parse() is supposed to throw an exception if the value cannot be converted. The whole point of .TryParse() is to avoid that. So, your methods need to be cleaned up and edited to actually accomplish something:
private bool WaistNumericCheck(out double waist)
{
bool canParse = double.TryParse(heighttextbox.Text, out waist);
if ( !canParse ) {
MessageBox.Show("Value must be numeric");
}
return canParse;
}
private bool HeightNumericCheck(out double height)
{
// todo -> same pattern as above
}
private void button1_Click(object sender, EventArgs e)
{
double height = 0, waist = 0;
if( WaistNumericCheck(waist) && HeightNumericCheck(height) )
{
CheckDimensions(height, waist);
/* ... the rest of your code */
}
}
This modifies your test methods to return a true/false based on whether the parse was successful, and outs your parsed variables so that you don't have to parse them again.
I suggest at some point that you review the MSDN documentation: http://msdn.microsoft.com/en-us/library/994c0zb1%28v=vs.110%29.aspx

Cannot implicit convert type "float" to Systems.Windows.Forms.Textbox

I have been trying for a little while now how to convert this.
How would you cast this in windows forms?
It doesnt seem to work like normal console applications....
Sorry if this seems dumb but I don't understand it.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
float input1 = 0;
float input2 = 0;
float output = 0;
int c = 0;
public Form1()
{
InitializeComponent();
}
private void button10_Click(object sender, EventArgs e)
{
textBox1.AppendText("0");
}
private void button11_Click(object sender, EventArgs e)
{
textBox1.Clear();
}
private void button17_Click(object sender, EventArgs e)
{
textBox1 = output;
}
private void button12_Click(object sender, EventArgs e)
{
switch(c)
{
case '+':
output = input1 + input2;
break;
}
}
private void button17_Click(object sender, EventArgs e)
{
textBox1.Text = output.ToString();
}
What the error is saying is textBox1 is a TextBox and you are trying to change this to be a Float; and there isn't any clear way of how to do this.
Most likely what you wanted to do was set the text of the textbox to be the value of the float.
textBox1.Text = output.ToString();
You should assign your values to Text property:
textBox1.Text = output.ToString();
This is the problem:
private void button17_Click(object sender, EventArgs e)
{
textBox1 = output;
}
What do you want to achieve?
Maybe:
private void button17_Click(object sender, EventArgs e)
{
textBox1.Text = output.ToString();
}
change it to
textBox1.Text = output.ToString();

c# scoping issue, simple fix i'm sure

So I have the following code, and It works nearly flawlessly, except for the fact that no matter what I do I cannot get the parts that are like: for (int.parse(txtGuess.Text) == numbGen) it will not recognize 'numbGen' no matter where I place it in the code. I cannot place it inside the button click function because I don't want the number to change, unless they've gotten it correct or re-opened the form.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class rndNum : Form
{
public rndNum()
{
}
private void rndNum_Load(object sender, EventArgs e)
{
int numbGen = RandMake(0, 100);
}
private void txtGuess_TextChanged(object sender, EventArgs e)
{
}
private void btnEval_Click(object sender, EventArgs e)
{
int guesses = 0;
while (txtGuess.Text != "")
{
if (int.Parse(txtGuess.Text) == numbGen)
{
MessageBox.Show("You got it!", "Congratulations!");
break;
}
else if (int.Parse(txtGuess.Text) > numbGen)
{
MessageBox.Show("Sorry, but you're too high. The number was " + numbGen + "!", "Please try again.");
txtGuess.Clear();
txtGuess.Focus();
guesses++;
break;
}
else if (int.Parse(txtGuess.Text) < numbGen)
{
MessageBox.Show("Sorry, but you're too low. The number was " + numbGen + "!", "Please try again.");
txtGuess.Clear();
txtGuess.Focus();
guesses++;
break;
}
}
}
private static int RandMake(int min, int max)
{
Random mkRnd = new Random();
return mkRnd.Next(min, max);
}
}
}
numbGen must be a class member.
Change
private void rndNum_Load(object sender, EventArgs e)
{
int numbGen = RandMake(0, 100);
}
to
private int numbGen;
private void rndNum_Load(object sender, EventArgs e)
{
numbGen = RandMake(0, 100);
}
actually you don't need to put the initialization in Form.Load, you can initialize a class member directly.
public partial class rndNum : Form
{
private int numbGen = RandMake(0, 100);
public rndNum()
{
}
and to further refine: if you want to make sure the values is not changed you can make it readonly
public partial class rndNum : Form
{
private readonly int numbGen = RandMake(0, 100);
public rndNum()
{
}
int numbGen;
private void rndNum_Load(object sender, EventArgs e)
{
numbGen = RandMake(0, 100);
}
try this!!!
The others already commented on the scoping issue you noticed. But your RandMake method is flawed too. You should not create an instance of Random for each number, but reuse the instance.
The problem here is that new Random() uses the time as seed, and the time only changes every few milliseconds. This means that if you call RandMake several times within that time interval you will get the same "random" number.
This doesn't seem to be a immediate problem because you only call it once, but you should be aware of this in the future.
When you put numbGen's declaration on the inside of a method, the number only exist in that functions scope. You have to place it outside like this:
int numbGen;
private void rndNum_Load(object sender, EventArgs e)
{
numbGen = RandMake(0, 100);
}

Categories