Having some trouble with my equals button - c#

this is the first real program I'm making for school, and I'm having some trouble with it. I believe my case structure and everything else is right, but when I attempt to add two numbers in my calculator, the text property for label 7 does not update.
This is my sample of how I have my case structure set up:
private void radioButton5_CheckedChanged(object sender, EventArgs e)
{
if (radioButton5.Checked == true)
rb = 5;
}
and then the actual case structure itself, as well as the rest of the code:
public void button1_Click(object sender, EventArgs e)
{
double num1 = 0;
double num2 = 0;
double result = 0;
string resultInLabel;
switch (rb)
{
case 1:
result = num1 + num2;
break;
case 2:
result = num1 - num2;
break;
case 3:
result = num1 * num2;
break;
case 4:
result = num1 / num2;
break;
case 5:
break;
}
resultInLabel = Convert.ToString(result);
resultInLabel = label7.Text;
}
button1 is my equals button, forgot to rename it. If more code is needed please let me know, first time posting and unsure how much more context is needed. Thanks for any answers.

If you want to change the text of the label you have to assign a value to it, not read its current value. Make your last line the following:
label7.Text = resultInLabel;

Related

Can't remove text from string using button

I'm trying to make a super simple program where you use 10 different buttons to write in a code (kind of like the code to the door of an appartment complex). All the buttons have this click event:
private void number_click(object sender, EventArgs e)
{
var button = (sender as Button);
if (code.Length == 4)
{
code.Remove(0, 1);
}
switch (button.Name)
{
case "button_1":
code += "1";
break;
case "button_2":
code += "2";
break;
case "button_3":
code += "3";
break;
case "button_4":
code += "4";
break;
case "button_5":
code += "5";
break;
case "button_6":
code += "6";
break;
case "button_7":
code += "7";
break;
case "button_8":
code += "8";
break;
case "button_9":
code += "9";
break;
case "button_0":
code += "0";
break;
}
label1.Text = code;
}
I'm simply trying to make so the number the user presses get added to the code string. When there length of the string reaches 4 it is supposed to remove the first character so that there is never more than 4 characters in the string. For some reason this doesn't seem to work. What am I doing wrong?
The immediate cause of the error is that string is immutable and so
code.Remove(0, 1);
computes result string and throws it away. You should assign the result string back:
...
code = code.Remove(0, 1);
...
You can get rid of long switch case and obtain digit from the button's name:
private void number_click(object sender, EventArgs e) {
var button = (sender as Button);
// Add new digit to the right
code += button.Name[button.Name.Length - 1].ToString();
// Ensure code is at most 5 digits long by removing digits from the left
code = code.Substring(Math.Clamp(code.Length - 5, 0, code.Length));
}
If you want to update the code variable you can use Substring method.
if (code.Length == 4)
{
code = code.Substring(1);
}
Your problem is caused by the fact that System.String instances are immutable. This means you can't modify the string code points to, but you can make it point to another string. The Remove method of System.String doesn't actually remove anything, it just creates a new string without the unwanted characters and returns a reference to it. This means that instead of
code.Remove(0, 1);
You want:
code = code.Remove(0, 1);

How can l change PictureBox when user does not estimate a letter correct?

I'm trying to make a hangman game in C#. I've done most of the work. I use dynamic buttons as keyboard. My problem is, that when user clicks on a letter on keyboard that is not present in the word that user should estimate, picturebox should replaced with picturebox2, and if his estimation is again wrong, replace with picturebox3, go on until final picturebox. However, if user estimates the letter correctly, picturebox should not replaced. I tried to do this, but my code does not work, as when I click on a button, picturebox keep changing until the last picture even if my estimation is correct or not. where is my mistake?
Here is the part of my code:
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.BackColor = Color.Aqua;
btn.ForeColor = Color.Red;
int a = 0;
// xy is the word that user should estimate
for (int i = 0; i < xy.Length; i++)
{
if (this.Controls.Find("txt" + i, true)[0].Text == btn.Text)
{
this.Controls.Find("txt" + i, true)[0].Text = btn.Text;
this.Controls.Find("txt" + i, true)[0].BackColor = Color.White;
}
else
{
a++;
switch(a)
{
case 1:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton1.png");
break;
case 2:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton2.png");
break;
case 3:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton3.png");
break;
case 4:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton4.png");
break;
case 5:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton5.png");
break;
default:
break;
}
}
}
}
First mistake is what Hans mentioned in comments: your variable must be a field of the class and not a local variable on the function, and must reset on each new game.
Second mistake: you check the letter the player clicked against every letter on the word, and for everytime it doesn't match, you add one to your error counter. You must add 1 only after you have finished checking all the letters in your word.
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.BackColor = Color.Aqua;
btn.ForeColor = Color.Red;
bool found = false;
// xy is the word that user should estimate
for (int i = 0; i < xy.Length; i++)
{
if (this.Controls.Find("txt" + i, true)[0].Text == btn.Text)
{
this.Controls.Find("txt" + i, true)[0].Text = btn.Text;
this.Controls.Find("txt" + i, true)[0].BackColor = Color.White;
found = true;
}
}
if (!found)
{
a++;
switch(a)
{
case 1:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton1.png");
break;
case 2:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton2.png");
break;
case 3:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton3.png");
break;
case 4:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton4.png");
break;
case 5:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton5.png");
break;
default:
break;
}
}
}
It still has a lot of room for improvement, buy I decided to stop here so you can eventually find it out by yourself while you're learning.

c# how to refer to current button

I am trying to make a minesweeper game using Windows Application. I would like to use a switch inside a method.
The problem:
public void switcher()
{
switch (x)
{
case 0:
A1.BackgroundImage = Image.FromFile("empty.jpg"); // look at A1
break;
case 1:
A1.BackgroundImage = Image.FromFile("1.jpg");
break;
case 2:
A1.BackgroundImage = Image.FromFile("2.jpg");
break;
case 3:
A1.BackgroundImage = Image.FromFile("3.jpg");
break;
case 4:
A1.BackgroundImage = Image.FromFile("4.jpg");
break;
case 5:
A1.BackgroundImage = Image.FromFile("5.jpg");
break;
case 6:
A1.BackgroundImage = Image.FromFile("6.jpg");
break;
case 7:
A1.BackgroundImage = Image.FromFile("7.jpg");
break;
case 8:
A1.BackgroundImage = Image.FromFile("8.jpg");
break;
}
}
As you can see, each of them says "A1. ....." A1 is my first button's name, but there are many other buttons as well. Is there a way I can refer to the button's properties, such as background image, without having to use its name? It would make programming so much easier.
Here's a simplified part of the button, if it helps:
private void A1_Click(object sender, EventArgs e) // < - I want to refer to this without using A1 name.
{
x = bombcount[0, 0];
switcher();
}
edit: One of the answers worked. I don't know much about these things, but I'll try to learn more about them! Thank you!
You need to refactor this code altogether. Don't rely on private members such as x like that, use method parameters:
private void SetButtonImage(Button button, int number)
{
string imagePath;
if (number == 0)
{
imagePath = "empty.jpg";
}
else
{
imagePath = number + ".jpg";
}
button.BackgroundImage = Image.FromFile(imagePath);
}
Then call it like this:
private void Button_Click(object sender, EventArgs e)
{
var button = sender as Button;
int number = bombcount[0, 0];
SetButtonImage(button, number);
}
Now you can hook up all button click events to that single event handler, and you can remove the x member, and you can remove the switch altogether.
Get a reference in switcher to the button being clicked like this:
private void A1_Click(object sender, EventArgs e)
{
Button myB = (Button) sender;
x = bombcount[0,0];
switcher(myB);
}
private void switcher(Button button)
{
switch (x)
{
case 0:
button.BackgroundImage = Image.FromFile("empty.jpg"); // look at A1
break;
case 1:
button.BackgroundImage = Image.FromFile("1.jpg");
break;
case 2:
button.BackgroundImage = Image.FromFile("2.jpg");
break;
case 3:
button.BackgroundImage = Image.FromFile("3.jpg");
break;
case 4:
button.BackgroundImage = Image.FromFile("4.jpg");
break;
case 5:
button.BackgroundImage = Image.FromFile("5.jpg");
break;
case 6:
button.BackgroundImage = Image.FromFile("6.jpg");
break;
case 7:
button.BackgroundImage = Image.FromFile("7.jpg");
break;
case 8:
button.BackgroundImage = Image.FromFile("8.jpg");
break;
}
}

C# programming error questions?

I am in a basic C# programming class, and I have been understanding everything up until I had to do the following exercise. If someone could check my code and help me out, that would be fantastic. I'm getting three different errors (CS1620, CS0266, and CS1955) in this code. I had a classmate try to help me out, but that did not work out so well.
Here is the exercise prompt:
Piecework workers are paid by the piece. Workers who produce a greater quantity of output are often paid at a higher rate.
Form: Use text boxes to obtain the person’s name and the number of pieces completed. Include a Calculate command button to display the dollar amount earned. You will need a Summary button to display the total number of pieces, the total pay, and the average pay per person. A clear button should clear the name and the number of pieces for the current employee.
Include validation to check for missing data. If the user clicks on the Calculate button without first entering a name and number of pieces, display a message box. Also, you need to make sure to not display a summary before any data are entered; you cannot calculate an average when no items have been calculated. You can check the number of employees in the Summary event procedure or disable the Summary command button until the first order has been calculated.
Pieces completed Price paid per piece for all pieces
1-199 .50
200-399 .55
400-599 .60
600 or more .65
Code:
public partial class pieceworkForm : Form
{
//Declare variables.
int tpiece = 0;
int numemp = 0;
float tpay = 0;
public pieceworkForm()
{
InitializeComponent();
}
private void exitButton_Click(object sender, EventArgs e)
{
//Closes form.
this.Close();
}
private void printButton_Click(object sender, EventArgs e)
{
//Prints form.
printForm1.PrintAction = System.Drawing.Printing.PrintAction.PrintToPreview;
printForm1.Print();
}
private void calcButton_Click(object sender, EventArgs e)
{
//Converts pieces to integer.
int pieces = 0;
pieces = int.Parse(piecesTextBox.Text.Trim());
//Calculates pay based on number of pieces completed.
float pay = calcButton(pieces);
//Display the formatted text in the pay label
payMaskedTextBox.Text = string.Format("C", pay);
payMaskedTextBox.Visible = true;
//Counts employees on click.
numemp = numemp + 1;
//Total pieces made.
tpiece = tpiece + pieces;
//Total pay.
tpay += pay;
//Enable summary button.
sumButton.Enabled = true;
}
private void clearButton_Click(object sender, EventArgs e)
{
//Clears form.
empTextBox.Text = string.Empty;
piecesTextBox.Text = string.Empty;
payMaskedTextBox.Text = string.Empty;
}
private void callButton_Click(object sender, EventArgs e)
{
//Confirm clear.
if ((MessageBox.Show("Do you want to clear this form?", "Confirm", MessageBoxButtons.YesNo) == DialogResult.Yes))
{
// Call the regular "Clear" button handler, as if it had been clicked as well.
clearButton_Click(sender, e);
//Reset everything to zero.
tpiece = 0;
tpay = 0;
numemp = 0;
// Make summary groupbox invisible.
summaryGroupBox.Visible = false;
// And disable summary button until new pay is entered.
sumButton.Enabled = false;
}
}
private void empTextBox_TextChanged(object sender, EventArgs e)
{
//Show message if field is empty.
if (string.IsNullOrWhiteSpace(empTextBox.Text))
{
MessageBox.Show("Please enter an employee name.");
}
}
private void piecesTextBox_TextChanged(object sender, EventArgs e)
{
//Show messgae if field is empty.
if (string.IsNullOrWhiteSpace(piecesTextBox.Text))
{
MessageBox.Show("Please enter the number of pieces completed.");
}
}
private float calc(int pieces)
{
float pay = 0;
switch (pieces)
{
case 0:
pay = 0;
break;
case 1: // 1 to 199
pay = pieces * 0.5;
break;
case 2: // 200 to 399
pay = pieces * 0.55;
break;
case 3: // 400 to 599
pay = pieces * 0.6;
break;
default:
pay = pieces * 0.65;
break;
}
return pay;
}
private void SetcalcButtonState()
{
// Assume false
calcButton.Enabled = false;
// Check for non-empty text
if (((empTextBox.Text.Trim().Length > 0) & (piecesTextBox.Text.Trim().Length > 0)))
{
int pieces = 0;
// TryParse will return true if the text is good as a number
if ((int.TryParse(piecesTextBox.Text.Trim(), pieces)))
{
calcButton.Enabled = true;
}
}
}
private void sumButton_Click(System.Object sender, System.EventArgs e)
{
//Show total pieces nd pay.
tpieceMaskedTextBox.Text = string.Format("{0}", tpiece);
tpayMaskedTextBox.Text = string.Format("C", tpay);
//Calculate and show average pay per employee.
avgMaskedTextBox.Text = string.Format("C", tpiece / numemp);
// Make the whole summary box visible
summaryGroupBox.Visible = true;
}
}
The specific problem areas are as follows:
CS1955 Non-invocable member 'pieceworkForm.calcButton' cannot be used like a method.
float pay = calcButton(pieces);
CS0266 Cannot implicitly convert type 'double' to 'float'. An explicit conversion exists (are you missing a cast?)
private float calc(int pieces)
{
float pay = 0;
switch (pieces)
{
case 0:
pay = 0;
break;
case 1: // 1 to 199
pay = pieces * 0.5;
break;
case 2: // 200 to 399
pay = pieces * 0.55;
break;
case 3: // 400 to 599
pay = pieces * 0.6;
break;
default:
pay = pieces * 0.65;
break;
}
return pay;
}
CS1620 Argument 2 must be passed with the 'out' keyword.
if ((int.TryParse(piecesTextBox.Text.Trim(), pieces)))
{
calcButton.Enabled = true;
}
CS1955 Non-invocable member 'pieceworkForm.calcButton' cannot be used
like a method.
Instead of calling a method you are calling an event handler. What you want to do is the following:
float pay = calc(pieces);
CS0266 Cannot implicitly convert type 'double' to 'float'. An explicit
conversion exists (are you missing a cast?)
You need to specify your real numbers as a float in order to save them into a float variable, as they are a double by default.
private float calc(int pieces)
{
float pay = 0f;
switch (pieces)
{
case 0:
pay = 0f;
break;
case 1: // 1 to 199
pay = pieces * 0.5f;
break;
case 2: // 200 to 399
pay = pieces * 0.55f;
break;
case 3: // 400 to 599
pay = pieces * 0.6f;
break;
default:
pay = pieces * 0.65f;
break;
}
return pay;
}
CS1620 Argument 2 must be passed with the 'out' keyword.
Passing any values by reference must be explicitly defined using the out keyword. You can read about it on MSDN.
if ((int.TryParse(piecesTextBox.Text.Trim(), out pieces)))
{
calcButton.Enabled = true;
}

can perform some operations but not all on c# calculator?

So far, my addition and subtraction work. But, my multiplication and division do not. This is because the first two numbers I put in get added and them the operation is done. Such as, if 9 * 9 + 3 should be 84, it is 21 on my calculator. That is because it is taking 9+9 + 3; as it only sees the last operator.
I have absolutely no idea how to fix this. Is there any helpful insight?
public partial class Form1 : Form
{
double num2;
double num1;
string c;
public Form1()
{
InitializeComponent();
}
private void btn0_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn0.Text;
}
private void btn1_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn1.Text;
}
private void btn2_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn2.Text;
}
private void btn3_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn3.Text;
}
private void btn4_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn4.Text;
}
private void btn5_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn5.Text;
}
private void btn6_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn6.Text;
}
private void btn7_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn7.Text;
}
private void btn8_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn8.Text;
}
private void btn9_Click(object sender, EventArgs e)
{
txtBox.Text = txtBox.Text + btn9.Text;
}
private void btnDecimal_Click(object sender, EventArgs e)
{
if (!txtBox.Text.Contains('.'))
txtBox.Text += '.';
}
private void btnClear_Click(object sender, EventArgs e)
{
txtBox.Clear();
}
private void btnAddition_Click(object sender, EventArgs e)
{
num1 = num1 + double.Parse(txtBox.Text);
c = "+";
txtBox.Clear();
}
private void btnSubtraction_Click(object sender, EventArgs e)
{
num1 = num1 + double.Parse(txtBox.Text);
c = "-";
txtBox.Clear();
}
private void btnMultiplication_Click(object sender, EventArgs e)
{
num1 = num1 + double.Parse(txtBox.Text);
c = "*";
txtBox.Clear();
}
private void btnDivision_Click(object sender, EventArgs e)
{
num1 = num1 + double.Parse(txtBox.Text);
c = "/";
txtBox.Clear();
}
private void btnEquals_Click(object sender, EventArgs e)
{
double result;
num2 = double.Parse(txtBox.Text);
switch (c)
{
case "+":
result = num1 + num2;
txtBox.Text = result.ToString();
num1 = 0;
break;
case "-":
result = num1 - num2;
txtBox.Text = result.ToString();
num1 = 0;
break;
case "*":
result = num1 * num2;
txtBox.Text = result.ToString();
num1 = 0;
break;
case "/":
if (num2 != 0)
{
result = num1 / num2;
txtBox.Text = result.ToString();
}
else
{
txtBox.Text = "You can't divide by zero... sign up for Math 100 please =)";
}
break;
default:
result = 0;
break;
}
}
}
}
You need to do the previous operation before overwriting it with a new one:
private void btnAddition_Click(object sender, EventArgs e)
{
num2 = double.Parse(txtBox.Text);
num1 = calc(num1, num2, c);
c = "+";
txtBox.Clear();
}
where calc does the operation that you do on "=" now.
Two issues:
Look at your num1 variable every time after you click an operator other than equal. Say I start with 6*4-3. I press 6, then *. At this point num1 now becomes 6. Press 4 and - next. Now 4 is Added to Num1 making 10. Then 3 and equal is pressed, which probably gave you 7.
Second issue:
c is being overridden every time you press a different operator such as + or minus.
Solutions:
1) You could make an infix parser or
2) Modify your code to something as follow (giving example for subtraction)
private void btnSubtraction_Click(object sender, EventArgs e)
{
Equals()
c = "-";
txtBox.Clear();
}
private void btnEquals_Click(object sender, EventArgs e)
{
Equals();
txtBox.Text = Result.ToString();
result = 0;
}
private void Equals()
{
if (!double.TryParse(txtBox.Text, out num2)) return;
switch (c)
{
case "+":
result = result + num2;
break;
case "-":
result = result - num2;
break;
case "*":
result = result * num2;
break;
case "/":
result = result / num2;
break;
default:
result = num2;
break;
}
}
I think your problem is num1. Everytime you do an opperation you are just adding num1 with the value of the text box.
So I think when you press the buttons: 6*4-3= you should get 21, but you are acrually getting 7
This is because num1 is being added when you press * and - buttons, so you end up doing 6+4-3 = 7.
You need to change btnMultiplication_Click to something like:
private void btnMultiplication_Click(object sender, EventArgs e)
{
num1 = num1 * double.Parse(txtBox.Text);
c = "*";
txtBox.Clear();
}
and something similar for divide and subtract. I think subtract only works in your example because it's the last thing you do and the equals button handles it correctly.
I haven't tested this out but I think that's your problem
The mistake is that you're doing, for every operator:
num1 = num1 + double.Parse(txtBox.Text);
and that's wrong, because you're only adding every number you write in your calculator, except the last one, which is calculated correctly, due to btnEquals_Click.
In fact you check what operator you're using only when "=" is pressed, you have to do that for every operator you choose.
When any operation (+, -, /, *, =) is performed, the existing state (including the last operation) should be evaluated and replaces your first number, operation and second number.
Look at your criteria, here's the state before/after each action:
2+2+2= 6
2+
before: firstNumber=0 (default), operation="+" (default, hidden), secondNumber=2
after: firstNumber=2 (calc 0+2), operation="+", secondNumber=empty (awaiting input)
2+2+
before: firstNumber=2, operation="+", secondNumber=2
after: firstNumber=4(calc 2+2), operation="+", secondNumber=empty (awaiting input)
2+2+2=
before: 4 + 2
after: 6 + (empty)
2+3-1= 4
2+
before: 0(default) +(default) 2
after: 2 + (empty)
2+3-
before: 2 + 3
after: 5 - (empty)
2+3-1=
before: 5 - 1
after: 4 +(inferred) (empty)
6*4-3= 21
6*
before: 0(default) +(default) 6
after: 6 * (empty)
6*4-
before: 6 * 4
after: 24 - (empty)
6*4-3=
before: 24 - 3
after: 21 +(inferred) (empty)
Does that make more sense?
Also to follow standard calculator conventions you might want to consider allowing people to change the operation if the 2nd number is currently empty, e.g.
given this sequence:
6*4=-3= - perform 6*4 and see result ("="), then subtract 3 from that and show that result ("=")
6*
before: 0(default) +(default) 6 -> 6 * (empty)
6*4=: 6 * 4
after: 24 +(inferred) (empty)
6*4=-
before: 24 + (empty)
after special case: 24 - (empty)
6*4=-3=
before: 24 - 3
after: 21 +(inferred) (empty)
UPDATE:
To put this in terms of your code, you would need to change the +, -, /, * and = buttons to all work the same way. That is, take num1, c and the current value of double.Parse(txtBox.Text), perform that operation then update based on the new operation.
// is the current txtBox value new, so will be cleared and allow op change
private bool isNew = true;
// change this to default to +
string c = "+";
double num1 = 0;
private void Evaluate(string newOperand)
{
if (isNew)
{
// just update the operand, don't perform an evaluate
c = newOperand;
return;
}
double num2 = double.Parse(txtBox.Text);
switch (c)
{
case "+":
num1 = num1 + num2;
break;
// etc for -, /, *
// for "="
default:
num1 = num1 + num2;
break;
}
isNew = true;
c = newOperand;
}
// this can be assigned as the handler for buttons 0 - 9
public void btnNumber_Click(object sender, EventArgs e)
{
var button = sender as Button;
txtBox.Text += button.Text;
isNew = false;
}
// this can be assigned as the event handler for all operations: +, -, /, *, =
public void btnOperation_Click(object sender, EventArgs e)
{
var button = sender as Button;
Evaluate(button.Text);
}
I have changed the whole purpose of num1 from the way you did it, so it is now the firstNumber as in my examples above.
You might want to add a clear all that will reset num1 to 0 and c to +. You could also do this in your existing btnClear_Click by detecting a 2nd press, like many calculators do:
public void btnClear_Click(object sender, EventArgs e)
{
if (isNew)
{
num1 = 0;
c = "";
// text box should already be empty
}
else
{
isNew = true;
txtBox.Clear();
}
}

Categories

Resources