I'm not sure if I'm writing the call correctly. 'intQty' says doesn't exist in current context. So how would I go about fixing that?
txtQty.Text = getPrice(intQty);
txtPrice.Text = decPrice.ToString("C2");
//Also to compute the order total it has to be written as
Order Total = (Order Qty * Price) * (1 + Tax Rate)
what I have: decTotal = (intQty * decPrice) * (1 + fltTaxRate);
so would I replace the that with values I've already declared?
EDIT: 'intQty' is declared right under the btnCalculate_Click as 'int intQty;'
there's data validation underneath and some methods as well.
FULL CODE:
string sCboStates;
int intQty;
string sWrapperSample;
// data validation
try
{
intQty = Convert.ToInt32(txtQty.Text);
}
catch
{
MessageBox.Show("Contents are not numeric.",
"Quantity",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
txtQty.Focus();
return;
}
try
{
sWrapperSample = Convert.ToString(txtWrapperSample.Text);
}
catch
{
MessageBox.Show("Content's empty.",
"Wrapper Sample",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
txtLine1.Focus();
return;
}
try
{
sCboStates = Convert.ToString(cboStates.Text);
}
catch
{
MessageBox.Show("Content's empty.",
"States",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
cboStates.Focus();
return;
}
}
// Method 1
private decimal getPrice(int intQty)
{
decimal decPrice;
if (intQty <= 500)
{
decPrice = 1.25m;
}
else if (intQty >= 501 && intQty <= 1000)
{
decPrice = 1.05m;
}
else if (intQty >= 1001 && intQty <= 5000)
{
decPrice = .90m;
}
else if (intQty > 5001)
{
decPrice = .75m;
}
decPrice = Convert.ToDecimal(txtPrice.Text);
txtQty.Text = intQty.ToString();
return intQty;
}
//Method 2
private float getTaxRate(string sCboStates)
{
string sStates = "";
float fltTaxRate=0;
if (sStates == "CT")
{
fltTaxRate = 0.06f;
}
else if (sStates == "MA")
{
fltTaxRate =.0625f;
}
else if (sStates == "ME")
{
fltTaxRate = .085f;
}
else if (sStates == "NH")
{
fltTaxRate = .0f;
}
else if (sStates == "RI")
{
fltTaxRate = .07f;
}
else if (sStates == "VT")
{
fltTaxRate = .06f;
}
return fltTaxRate;
}
//Method 3
private void formatWrapperSample()
{
txtWrapperSample.Text = txtLine1.Text + " " +
Environment.NewLine +
txtLine2.Text + " " +
Environment.NewLine +
txtLine3.Text;
}
// Method 4
private Color GetColor(string sColorIn)
{
return Color.FromName(sColorIn);
//CALCULATIONS
decimal decTotal = 0;
//Call the price method by passing the numeric value and the text qty
txtQty.Text = getPrice(intQty);
txtPrice.Text = decPrice.ToString("C2");
// Compute the total
decTotal = (intQty * decPrice) * (1 + fltTaxRate);
txtTotal.Text = decTotal.ToString("C2");
}
private void cboWrapperColor_SelectedIndexChanged(object sender, EventArgs e)
{
//Label Color 'cboWrapperColor_Selected' is a typo
txtWrapperSample.BackColor = GetColor(cboLabelColor.Text);
}
private void cboFontColor_SelectedIndexChanged(object sender, EventArgs e)
{
txtWrapperSample.ForeColor = GetColor(cboFontColor.Text);
}
private void cboStates_SelectedIndexChanged(object sender, EventArgs e)
{
getTaxRate("P2");
}
private void btnClear_Click(object sender, EventArgs e)
{
txtLine1.Clear();
txtLine2.Clear();
txtLine3.Clear();
txtQty.Clear();
txtWrapperSample.Clear();
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
It looks like there is some code missing, is everything starting with //CALCULATIONS to the end of the code part of the GetColor() method?
At any rate, you're declaring and initializing intQty in your btnCalculate_Click event handler. This means that the rest of your program does not know about intQty (with the exception of GetPrice() since you're passing it in).
Declare intQty as a global variable at the top of your class and then set the correct value in btnCalculate_Click
That way when you go to do the calculations it will know about intQty
Also...
You are using exceptions to control program flow, which is generally considered bad practice.
Exceptions are for exceptional cases, because they are computationally expensive.
You should use Int32.TryParse() instead
txtQty.Text = getPrice(intQty);
For one your method returns Decimal - you can't assign it to String property. C# is stringly typed.
Related
I am trying to make a form using C# that is similar to a calculator.
I have to code a method named IsOperator that checks that the text box that’s passed to it contains a value of +, -, *, or /.
For some reason it is not validating correctly.
I've tried changing the || to && and reversing the returns to false and true but nothing works.
When I try putting other things in the operator text box that are not + / - * the results turn into 0. Nothing ends up validating.
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 SimpleCalculator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCalc_Click(object sender, EventArgs e)
{
try
{
if (IsValidData())
{
MessageBox.Show("Error");
}
else
{
decimal operand1 = Convert.ToDecimal(txtOperand1.Text);
string operator1 = txtOperator.Text;
decimal operand2 = Convert.ToDecimal(txtOperand2.Text);
decimal result = 0;
if (operator1 == "+")
result = operand1 + operand2;
else if (operator1 == "-")
result = operand1 - operand2;
else if (operator1 == "*")
result = operand1 * operand2;
else if (operator1 == "/")
result = operand1 / operand2;
result = Math.Round(result, 4);
txtResult.Text = result.ToString();
txtOperand1.Focus();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\n\n" +
ex.GetType().ToString() + "\n" +
ex.StackTrace, "Exception");
}
}
public bool IsValidData()
{
return
//validate the operand1 text box
IsPresent(txtOperand1, "Operand 1") &&
IsDecimal(txtOperand1, "Operand 1") &&
IsWithinRange(txtOperand1, "Operand 1", 0, 1000000) &&
//validates the operator text box
IsPresent(txtOperator, "Operator") &&
IsOperator(txtOperator, "Operator") &&
//validates the operand 2 text box
IsPresent(txtOperand2, "Operand 2") &&
IsDecimal(txtOperand2, "Operand 2") &&
IsWithinRange(txtOperand2, "Operand 2", 0, 1000000);
}
private void btnExit_Click(object sender, System.EventArgs e)
{
this.Close();
}
//is present
public bool IsPresent(TextBox textBox, string name)
{
if (textBox.Text == "")
{
MessageBox.Show(name + " is a required field.", "Entry Error");
textBox.Focus();
}
return false;
}
//is decimal
public bool IsDecimal(TextBox textBox, string name)
{
decimal number = 0m;
if (Decimal.TryParse(textBox.Text, out number))
{
return true;
}
else
{
MessageBox.Show(name + " must be a decimal value.", "Entry Error");
textBox.Focus();
return false;
}
}
//is within range
public bool IsWithinRange(TextBox textBox, string name, decimal min, decimal max)
{
decimal number = Convert.ToDecimal(textBox.Text);
if (number < min || number > max)
{
MessageBox.Show(name + "must be between" + min.ToString()
+ "and" + max.ToString() + ".", "Entry Error");
textBox.Focus();
return false;
}
return true;
}
//is a valid operator
public bool IsOperator(TextBox textBox, string name)
{
string operator1 = "";
operator1 = Convert.ToString(textBox.Text);
if (operator1 == "+" && operator1 == "-" && operator1 == "/" && operator1 == "*")
{
MessageBox.Show("Please enter a valid operator in the operator text box.", "Entry Error");
return false;
}
return true;
}
private void txtOperand1_TextChanged(object sender, EventArgs e)
{
this.txtResult.Text = "";
}
private void txtOperator_TextChanged(object sender, EventArgs e)
{
this.txtResult.Text = "";
}
private void txtOperand2_TextChanged(object sender, EventArgs e)
{
this.txtResult.Text = "";
}
}
}
Fist of all you should not use someString == "" instead use string.IsNullOrEmpty(someString) or string.IsEmptyOrWhitespace(someString). 1
Then IsPresent always returns false. You may change that method to
public bool IsPresent(TextBox textBox, string name)
{
if (!string.IsNullOrEmpty(textBox.Text))
{
return true;
}
MessageBox.Show(name + " is a required field.", "Entry Error");
textBox.Focus();
return false;
}
In the EventHandler your forgot a ! before IsValidData(). You you're showing an Error, when the data is valid and try to perform the calculation, when your data is faulty.
Your IsOperator Method contains in fact a logical issue. You want to return true, if the operator is any of the following chars +, -, *, \. So its easier to flip the if logic to something like this using LINQ
//is a valid operator
public bool IsOperator(TextBox textBox, string name)
{
string operator = textBox.Text;
if (new[] {"+", "-", "*", "/"}.Contains(operator))
{
return true;
}
MessageBox.Show("Please enter a valid operator in the operator text box.", "Entry Error");
return false;
}
I think your code also could benefit from using Exceptions instead of showing MessageBoxes as soon an error occurs.
I try to make a automatic format system for money, for example: to digit the number 5124.25
the user types 5: 0,05
the user types 1: 0,51
the user types 2: 5,12
the user types 4: 51,24
the user types 2: 512,42
the user types 5: 5124,25
I need to put this "format style" in one column of datagridview, for this, I try this:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
var temp = (DataGridView)sender;
if (temp.CurrentCell.ColumnIndex == 4)
{
e.Control.PreviewKeyDown -= Control_PreviewKeyDown;
e.Control.PreviewKeyDown += new PreviewKeyDownEventHandler(Control_PreviewKeyDown);
}
}
void Control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
var temp = (DataGridViewTextBoxEditingControl)sender;
TextBoxMoeda(ref temp, e);
/*if (e.KeyCode == Keys.Escape)
{
System.Diagnostics.Debug.Print("escape pressed");
}*/
}
public static void TextBoxMoeda(ref DataGridViewTextBoxEditingControl txt, PreviewKeyDownEventArgs e)
{
string n = string.Empty;
double v = 0;
try
{
n = txt.Text.Replace(",", "").Replace(".", "").Replace("R$", "");
if (n.Length == 0)
txt.Text = "0,00";
else if (n.Length == 1)
txt.Text = "0,0" + n;
else if (n.Length == 2)
txt.Text = "0," + n;
else if(n.Length > 2)
txt.Text = n.Substring(0, n.Length - 2) + "," +
n.Substring(n.Length - 2);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "TextBoxMoeda");
}
}
How It's possible to make this dinamic format for money ?
Try setting the DefaultCellStyle.Format to "c" for money or whatever format you want, and then subscribe to the CellFormatting event:
dataGridView1.Columns["Column2"].DefaultCellStyle.Format = "c";
dataGridView1.CellFormatting += dataGridView1_CellFormatting;
Try parsing the information into a decimal for your formatting:
void dataGridView1_CellFormatting(object sender,
DataGridViewCellFormattingEventArgs e) {
if (e.CellStyle.Format == "c" &&
e.RowIndex != this.dataGridView1.NewRowIndex) {
decimal d;
if (e.Value != null && decimal.TryParse(e.Value.ToString(), out d)) {
e.Value = d.ToString("c");
}
}
}
private void button1_Click(object sender, EventArgs e)
{
double temp = double.Parse(textBox1.Text);
if (temp < 0)
{
label2.Text = "Freezing.";
}
if (temp > 40)
{
label2.Text = "Hot.";
}
else
{
label2.Text = "Moderate.";
}
}
Whenever converting user input, or any form of type String in to an object, I always like to use TryParse(...) as it provides you with better control if something isn't right.
double temp = 0.0d;
var converted = double.TryParse(textBox1.Text, out temp);
if (!converted) throw new Exception("Please enter a positive or negative temperature.");
if (temp < 0.0d)
{
// Freezing
}
else if (temp >= 0.0d && temp < 40.0d)
{
// Moderate
}
else if (temp >= 40.0d)
{
// Hot
}
The key is finding out what the value is being read in to temp. If its bringing in a negative number then I would recommend the code change below. What its really doing is if the 1st isnt true, then it checks the second, and finally it uses the third if neither are true.
private void button1_Click(object sender, EventArgs e)
{
double temp = double.Parse(textBox1.Text);
if (temp < 0)
{
label2.Text = "Freezing.";
}
else if (temp > 40)
{
label2.Text = "Hot.";
}
else
{
label2.Text = "Moderate.";
}
}
if (getchar == '+') {
answer = getnum1+getnum2; // if the random operation is add, it will add
addtemp++; // <---- disregard this
if (answer == getanswer) // the answer from my textbox which is
{ // user-input it is stored on "getanswer"
correct++; // it is compared if its correct or wrong
addcomp++;
}
else { wrong++; }
}
else if (getchar == '-') {
subtemp++;
answer = nextValue - nextValue1;
if (answer == getanswer) {
correct++;
subcomp++;
}
else { wrong++; }
}
else if (getchar == '*') {
multemp++;
answer = nextValue * nextValue1;
if (answer == getanswer) {
correct++;
mulcomp++;
}
else { wrong++; }
}
else if (getchar == '/') {
divtemp++;
answer = nextValue / nextValue1;
if (answer == getanswer) {
correct++;
divcomp++;
}
else { wrong++; }
}
else if (getchar == '%') {
modtemp++;
answer = nextValue % nextValue1;
if (answer == getanswer) {
correct++;
modcomp++;
}
else { wrong++; }
}
C# programming HELP! Now whenever i press the button "SCORES" it is a MessageBox.Show(correct or wrong) , the values are wrong. it sometimes increment corrected but just once or twice.Is there something wrong with my code?
///////////////////////////////////////////////////////////
ENTIRE CODE for #boncodigo
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 A1_ALS_Noroña
{
public partial class Form1 : Form
{
int minV=0, maxV=0,ques=0,tempques=1;
int addtemp, subtemp, multemp, divtemp, modtemp;
int addcomp, subcomp, mulcomp, divcomp, modcomp;
int answer,getanswer;
int getnum1, getnum2;
char getchar;
char[] select = new char[5];
int count=0;
int correct, wrong;
public Form1()
{
InitializeComponent();
}
private void bttnstart_Click(object sender, EventArgs e)
{
bttnanswer.Enabled = true;
grpbox1.Enabled = false;
bttnanswer.Enabled = true;
lblnum1.Visible = true;
lblnum2.Visible = true;
lbloperator.Visible = true;
bttnstop.Enabled = true;
bttnscore.Enabled = true;
bttnstart.Enabled = false;
Random random = new Random();
int nextValue = random.Next(minV, maxV);
int nextValue1 = random.Next(minV, maxV);
lblnum1.Text = nextValue.ToString();
lblnum2.Text = nextValue1.ToString();
var rand = new Random();
char num = select[rand.Next(count)];
lbloperator.Text = Convert.ToString(num);
}
private void txtboxmin_TextChanged(object sender, EventArgs e)
{
minV = Convert.ToInt32(txtboxmin.Text);
}
private void txtbxmax_TextChanged(object sender, EventArgs e)
{
maxV = Convert.ToInt32(txtbxmax.Text);
}
private void bttnexit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void bttnstop_Click(object sender, EventArgs e)
{
MessageBox.Show("APPLICATION STOP! The application will restart.");
Application.Restart();
}
private void bttnanswer_Click(object sender, EventArgs e)
{
tempques++;
Random random = new Random();
int nextValue = random.Next(minV,maxV);
int nextValue1 = random.Next(minV, maxV);
lblnum1.Text = nextValue.ToString();
var rand = new Random();
char num = select[rand.Next(count)];
lbloperator.Text = Convert.ToString(num);
lblnum2.Text = nextValue1.ToString();
getnum1 = Convert.ToInt32(lblnum1.Text);
getnum2 = Convert.ToInt32(lblnum2.Text);
getanswer = Convert.ToInt32(txtbxans.Text);
getchar = Convert.ToChar(lbloperator.Text);
if (getchar == '+')
{
answer = getnum1 + getnum2;
addtemp++;
if (answer == getanswer)
{
correct++;
addcomp++;
}
else
{
wrong++;
}
}
else if (getchar == '-')
{
subtemp++;
answer = nextValue - nextValue1;
if (answer == getanswer)
{
correct++;
subcomp++;
}
else
{
wrong++;
}
}
else if (getchar == '*')
{
multemp++;
answer = nextValue * nextValue1;
if (answer == getanswer)
{
correct++;
mulcomp++;
}
else
{
wrong++;
}
}
else if (getchar == '/')
{
divtemp++;
answer = nextValue / nextValue1;
if (answer == getanswer)
{
correct++;
divcomp++;
}
else
{
wrong++;
}
}
else if (getchar == '%')
{
modtemp++;
answer = nextValue % nextValue1;
if (answer == getanswer)
{
correct++;
modcomp++;
}
else
{
wrong++;
}
}
}
private void txtbxques_TextChanged(object sender, EventArgs e)
{
ques = Convert.ToInt32(txtbxques.Text);
}
private void chkbxtimer_CheckedChanged(object sender, EventArgs e)
{
rdoeasy.Enabled = true;
rdomed.Enabled = true;
rdohard.Enabled = true;
}
private void chkboxAdd_CheckedChanged(object sender, EventArgs e)
{
if (chkboxAdd.Checked == true)
{
select[count] = '+';
count++;
}
else if (chkboxAdd.Checked == false)
{
Array.Clear(select, 0, select.Length);
count--;
}
}
private void chkboxSub_CheckedChanged(object sender, EventArgs e)
{
if (chkboxSub.Checked == true)
{
select[count] = '-';
count++;
}
else if (chkboxSub.Checked == false)
{
Array.Clear(select, 0, select.Length);
count--;
}
}
private void chkboxMul_CheckedChanged(object sender, EventArgs e)
{
if (chkboxMul.Checked == true)
{
select[count] = '*';
count++;
}
else if (chkboxMul.Checked == false)
{
Array.Clear(select, 0, select.Length);
count--;
}
}
private void chkboxDiv_CheckedChanged(object sender, EventArgs e)
{
if (chkboxDiv.Checked == true)
{
select[count] = '/';
count++;
}
else if (chkboxDiv.Checked == false)
{
Array.Clear(select, 0, select.Length);
count--;
}
}
private void chkboxMod_CheckedChanged(object sender, EventArgs e)
{
if (chkboxMod.Checked == true)
{
select[count] = '%';
count++;
}
else if (chkboxMod.Checked == false)
{
Array.Clear(select, 0, select.Length);
count--;
}
}
private void bttnscore_Click(object sender, EventArgs e)
{
MessageBox.Show("Correct Answer"+correct);
}
}
}
One thing in advance: I don't know where your bug is. Here's just a couple of tips that I think it would make sense if you think about them, in order to avoid similar bugs in the future:
If I had to review this code, my major issue would be with the amount of repeating code, where very similar multi-line long patterns are copied over and over. I think in the whole code you don't call any method, but implement stuff right away in the event-handlers, thereby repeating yourself and multiplying the potential for bugs. Let's look at this code:
if (chkboxSub.Checked == true)
{
select[count] = '-';
count++;
}
else if (chkboxSub.Checked == false)
{
Array.Clear(select, 0, select.Length);
count--;
}
apart from the bug with count when you have added several operators to the select-array, this code repeats several times. Let's extract the code into a method and make the bits that change parameterizable:
void AddOrRemoveOperator(bool isChecked, char operatorChar) {
if (isChecked) {
select[count] = operatorChar;
count++;
}
else {
Array.Clear(select, 0, select.Length);
count--;
}
}
Now you can call that method many times, e.g. like:
AddOrRemoveOperator(chkboxSub.Checked, '-');
Next point would be lack of .NET Base Class Library knowledge (BCL). E.g., wouldn't it be easier to use a List<T> instead of an array?
The above method becomes:
void AddOrRemoveOperator(bool isChecked, char operatorChar) {
if (isChecked) {
select.Add(operatorChar);
}
else {
select.Clear();
}
}
An Observation: All operators except the add one use the values nextValue, nextValue1 while the add one uses getnum1 and 2. Is that intended?
Short of extracting the code blocks in bttnanswer_Click into their own class, you can also extract the repeating code into a method:
void PerformComparison(Func<int> answerProvider,
ref int operatorCount,
ref int operatorSpecificCorrectCount)
{
var answer = answerProvider();
operatorCount++;
if (answer == getanswer) {
correct++;
operatorSpecificCorrectCount++;
}
else {
wrong++;
}
}
That code would still drive me mad (because the class you have programmed lacks cohesion), but we have fought code duplication. Now you can call the method e.g. like that:
if (getchar == '+')
{
PerformComparison(()=>getnum1 + getnum2, ref addtemp, ref addcomp);
}
There are many techniques to morph code into forms that are more easily testable and maintainable (refactoring), we have only used extract method so far. For more techniques the book Refactoring: Improving the Design of Existing Code is still highly recommendable.
It might be a float precision issue (maybe your user is entering 3 and the program calculates 2.9999999). Debug your code and identify one case when it is not adding correctly.
I am trying to figure out how to clear & display (reset) my cleared form values after an incorrect value has been entered and detected. Currently when I catch an incorrect input, it just sits there, even after i have clicked the enter button again. Any help would be greatly appreciated.
namespace Mileage
{
public partial class Form2 : Form
{
private double beginMileage, endMileage, gallons, mpg;
public Form2()
{
InitializeComponent();
}
//Enter button click
public void menuItem1_Click(object sender, EventArgs e)
{
if (endMileage<beginMileage)
{
this.label5.Text = String.Format("ERROR: End mileage is less than begining mileage.");
}
else if((endMileage<0)||(beginMileage<0))
{
this.label5.Text = String.Format("ERROR: One or more mileage input is negative.");
}
else if ((endMileage == 0) || (gallons == 0))
{
this.label5.Text = String.Format("ERROR: The end mileage and/or gallon input is zero.");
}
else
{
beginMileage = double.Parse(this.textBox1.Text.Replace(" ", ""));
endMileage = double.Parse(this.textBox2.Text.Replace(" ", ""));
gallons = double.Parse(this.textBox3.Text.Replace(" ", "")) ;
mpg = ((endMileage - beginMileage) / gallons);
this.label5.Text = String.Format("{0}", mpg);
}
}
//exit button click
public void menuItem2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
Uhm. . . so I figured it out. It was just a logic error that I had done :)
namespace Mileage
{
public partial class Form2 : Form
{
private float beginMileage, endMileage, gallons, mpg;
public Form2()
{
InitializeComponent();
}
public void menuItem1_Click(object sender, EventArgs e)
{
beginMileage = float.Parse(this.textBox1.Text.Replace(" ", ""));
endMileage = float.Parse(this.textBox2.Text.Replace(" ", ""));
gallons = float.Parse(this.textBox3.Text.Replace(" ", ""));
if((endMileage<0)||(beginMileage<0)||(gallons<0))
{
this.label5.Text = String.Format("ERROR: One or more input(s) is negative.");
this.textBox1.Text = " ";
this.textBox2.Text = " ";
this.textBox3.Text = " ";
}
else if ((endMileage == 0) || (gallons == 0))
{
this.label5.Text = String.Format("ERROR: The end mileage and/or gallon input is zero.");
this.textBox1.Text = " ";
this.textBox2.Text = " ";
this.textBox3.Text = " ";
}
else if (endMileage < beginMileage)
{
this.label5.Text = String.Format("ERROR: End mileage is less than begining mileage.");
this.textBox1.Text = " ";
this.textBox2.Text = " ";
this.textBox3.Text = " ";
}
else
{
mpg = ((endMileage - beginMileage) / gallons);
this.label5.Text = String.Format("{0}", mpg);
}
}
public void menuItem2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}