Screenshot of the Form First time poster, and im in need of some help here. I am working on a program that calculates an athletes salary after hiring agents, lawyers, agents, etc. I have a listbox that displays the salary*the constant percentage of the agent. I CANNOT seem to get the sum of the numbers entered so i can subtract them from the total salary and display it in a label. I would love some help, very new to C#.
The area in question is commented out under the Switch
public partial class athleteForm : Form
{
public athleteForm()
{
InitializeComponent();
}
const decimal LAWYER_PERCENT = 0.10m;
const decimal AGENT_PERCENT = 0.05m;
const decimal PA_PERCENT = 0.03m;
const decimal TRAINER_PERCENT = 0.07m;
const string LAWYER_STRING = "Lawyer";
const string AGENT_STRING = "Agent";
const string PA_STRING = "Personal Assistant";
const string TRAINER_STRING = "Trainer";
string profFirstName;
string profLastName;
string profSelect;
decimal profPay;
public void athleteForm_Load(object sender, EventArgs e)
{
}
public void profAddButton_Click(object sender, EventArgs e)
{
decimal startingSalary = Convert.ToDecimal(startingSalaryText.Text);
profFirstName = profFirstNameText.Text;
profLastName = profLastNameText.Text;
profSelect = profComboBox.GetItemText(profComboBox.SelectedItem);
decimal lawyerPay = startingSalary * LAWYER_PERCENT;
decimal agentPay = startingSalary * AGENT_PERCENT;
decimal trainerPay = startingSalary * TRAINER_PERCENT;
decimal paPay = startingSalary * PA_PERCENT;
switch (profComboBox.GetItemText(profComboBox.SelectedItem))
{
case "Lawyer":
profPay = lawyerPay;
break;
case "Agent":
profPay = agentPay;
break;
case "Trainer":
profPay = trainerPay;
break;
case "Personal Assistant":
profPay = paPay;
break;
}
profListBox.Items.Add(profFirstName + " " + profLastName + " " + profSelect);
profPayList.Items.Add("$ " + profPay);
//decimal sumOfListbox =
// (from string S in profPayList.Items
// select Convert.ToDecimal(S))
// .Sum();
decimal sum =
profPayList.Items
.Cast<string>()
.Sum(v =>
{
decimal d;
return decimal.TryParse(v, out d) ? d : 0m;
});
remainSalaryLabel.Text = (sum.ToString());
}
public void clearButton_Click(object sender, EventArgs e)
{
switch (MessageBox.Show("Are you sure you want to clear all professionals?",
"WonderWord",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question))
{
case DialogResult.Yes:
profListBox.Items.Clear();
profPayList.Items.Clear();
remainSalaryLabel.Text = " ";
break;
case DialogResult.No:
// "No" processing
break;
case DialogResult.Cancel:
// "Cancel" processing
break;
}
}
}
}
The problem is that you are storing your data as a string prefixed with a dollar sign ($). e.g. "$5";
When your are calculating the sum of all of your data, you are correctly using a decimal.TryParse to convert the string to a decimal. However, in this case, the TryParse will not succeed in extracting the number due to the dollar sign.
Therefore, your options for fix this are:
Remove the dollar sign before parsing;
Use the Decimal.TryParse overload that handles numberstyles and currency symbols;
Maintain a separate list of numbers to sum instead of storing them within the ListBox so you don't have to deal with the dollar sign. If you wish to still display the numbers, you can still bind the list of numbers to the ListBox and update whenever a new number is added.
Option 2 would be your best option for the current state of your code. Assuming you're dealing with US culture, your code will need to look similar to this:
NumberStyles style = NumberStyles.Number | NumberStyles.AllowCurrencySymbol;
CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
decimal sum = profPayList.Items
.Cast<string>()
.Sum(v =>
{
decimal d;
return decimal.TryParse(v, style, culture, out d) ? d : 0m;
});
Option 3 is what I would be going with if you have time to rewrite what you have as it will solve some other potentially issues with your code that could arise in the future.
Related
In my program I am using a database containing a Time (string previousTimeVASN).
I have a timer to clock total seconds. i would like to display the sum of previousTimeVASN + the total seconds.
I have error showing:
"System.FormatException: 'Input string was not in a correct format.'" at line: double test1 = Convert.ToDouble(previousTimeVASN);
any suggestion are much appreicated.
private void sNbtn_Click(object sender, RoutedEventArgs e)
{
TabControl.SelectedIndex = 1;
dtVASN.Tick += new EventHandler(dtVASN_Tick);
dtVASN.Interval = new TimeSpan(0, 0, 0, 0, 1);
}
void dtVASN_Tick(object sender, EventArgs e)
{
if (swVASN.IsRunning)
{
TimeSpan tsVASN = swVASN.Elapsed;
double test = tsVASN.TotalSeconds;
double test1 = Convert.ToDouble(previousTimeVASN);
txtVASN.Text = (test + test1).ToString();
}
}
The method Convert.ToDouble will throw FormatException if value is not a number in a valid format. You are getting the same here means either the value in previousTimeVASN is not a number or it is not in the expected format. Here is an alternate option for you to check whether the conversion is possible or not, that is, Double.TryParse Method
Converts the string representation of a number in a specified style
and culture-specific format to its double-precision floating-point
number equivalent. A return value indicates whether the conversion
succeeded or failed.
So the code can be revamped as like the following:
if (swVASN.IsRunning)
{
TimeSpan tsVASN = swVASN.Elapsed;
double test = tsVASN.TotalSeconds;
double test1;
Double.TryParse(previousTimeVASN, out test1);
txtVASN.Text = (test + test1).ToString();
}
if you want to alert the user that the second number is not valid then you can use the return value of parse like the following:
if(Double.TryParse(previousTimeVASN, out test1))
txtVASN.Text = (test + test1).ToString();
else
txtVASN.Text = "previous Time VASN is not valid:'
The problem of my code is if I put value in pay money(textbox) and I turned to zero giving me an error
System.FormatException: 'Input string was not in a correct format.'
This is my code :
private void txtPM_TextChanged(object sender, EventArgs e)
{
string fee = lblFee.Text.Trim();
string pm = txtPM.Text.Trim();
int number = Convert.ToInt32(fee);
int number2 = Convert.ToInt32(pm);
int minus = number2 - number;
txtChange.Text = minus.ToString().Trim();
}
I will put here the form
I hope you can help me thanks guys
You may need Convert.ToDecimal() if you are working with monetary values specified as decimals. (I second the empty and null checking suggestions)
Update for clarification:
Currently, you are converting string to Int32 with the following:
int number = Convert.ToInt32(fee);
int number2 = Convert.ToInt32(pm);
You can instead convert to decimal with the following:
decimal number = Convert.ToDecimal(fee);
decimal number2 = Convert.ToDecimal(pm);
Update2 (full method updated with null and empty checks):
private void txtPM_TextChanged(object sender, EventArgs e)
{
string fee = lblFee.Text.Trim();
string pm = txtPM.Text.Trim();
decimal number = 0;
decimal number2 = 0;
if(!string.IsNullOrWhiteSpace(fee)) number = Convert.ToDecimal(fee);
if(!string.IsNullOrWhiteSpace(pm)) number2 = Convert.ToDecimal(pm);
decimal minus = number2 - number;
txtChange.Text = minus.ToString().Trim();
}
Use the decimal type because it's more appropriate for financial and monetary calculations. To avoid the exception use decimal.TryParse. If the strings pm and fee are not in the right format decimal.TryParse will return zero and no exception will be thrown. You can also remove the Trim() on the last line.
private void txtPM_TextChanged(object sender, EventArgs e)
{
string fee = lblFee.Text.Trim();
string pm = txtPM.Text.Trim();
decimal number;
decimal.TryParse(fee, out number);
decimal number2;
decimal.TryParse(pm, out number2);
decimal minus = number2 - number;
txtChange.Text = minus.ToString();
}
You can use TryParse as already pointed out in the duplicate.
Also it makes more sense to use decimal when working with monetary values.
private void txtPM_TextChanged(object sender, EventArgs e)
{
decimal.TryParse(lblFee.Text, out decimal number);
decimal.TryParse(txtPM.Text, out decimal number2);
txtChange.Text = (number2 - number).ToString();
}
When using C# 6.0 or earlier you have to declare the variables in a separate statement:
private void txtPM_TextChanged(object sender, EventArgs e)
{
decimal number;
decimal.TryParse(lblFee.Text, out number);
decimal number2;
decimal.TryParse(txtPM.Text, out number2);
txtChange.Text = (number2 - number).ToString();
}
I'm trying to make a calculator, and I'm kinda stuck at the mod and exp operations, whenever I try to use them I get below error:
System.FormatException: 'Input string was not in a correct format.'
This is the event in which the error happens :
private void Equal_Click(object sender, EventArgs e)
{
switch (operationPerf)
{
case "+":
TB.Text = (result + Double.Parse(TB.Text)).ToString();
CO.Text = "";
break;
case "-":
TB.Text = (result - Double.Parse(TB.Text)).ToString();
CO.Text = "";
break;
case "*":
TB.Text = (result * Double.Parse(TB.Text)).ToString();
CO.Text = "";
break;
case "/":
TB.Text = (result / Double.Parse(TB.Text)).ToString();
CO.Text = "";
break;
case "Mod":
TB.Text = (result % Double.Parse(TB.Text)).ToString();
CO.Text = "";
break;
case "Exp":
TB.Text = Math.Exp(Double.Parse(TB.Text) * Math.Log((result) * 4)).ToString();
CO.Text = "";
break;
default:
break;
}
result = Double.Parse(TB.Text); // Here is where the error happens
CO.Text = "";
}
Probably operationPerf is none of the expected operators, so the default case is executed and the textbox still contains the original expression (e.g. "23Exp3"), which, of course, cannot be converted to a double.
You should really separate the calculator logic from input and output. Create a Calculator class in a separate code file (Calculator.cs)
public class Calculator
{
public double Result { get; set; }
public void Calculate(string operation, double operand)
{
switch (operation)
{
case "+":
Result = Result + operand;
break;
case "-":
Result = Result - operand;
break;
case "*":
Result = Result * operand;
break;
case "/":
Result = Result / operand;
break;
case "Mod":
Result = Result % operand;
break;
case "Exp":
Result = Math.Exp(operand * Math.Log(Result * 4));
// Did you want this instead?
// Result = Math.Pow(Result, operand);
break;
default:
break;
}
}
}
It is easier to understand, as it does only contain pure math and does not require any parsing or formatting.
In a form field (at the top of the form class) you can then declare
public partial class Form1 : Form
{
private Calculator _calculator = new Calculator();
...
}
The event handler is the easier too
private void Equal_Click(object sender, EventArgs e)
{
if (Double.TryParse(TB.Text, out double operand)) {
_calculator.Calculate(operationPerf, operand);
TB.Text = _calculator.Result.ToString();
CO.Text = "";
} else {
MsgBox.Show("The TextBox does not contain a number");
}
}
If the textbox still contains "23Exp3", you will not be able to convert it to a double. Either use different textboxes to enter the operation, the operator (a number) and the result, or separate the string into its three parts (the 2 numbers and the operation).
I really don't understand the logic behind Math.Exp(operand * Math.Log(Result * 4)). Since I do not know the expected behavior, I cannot give you any advice. Did you want to use Math.Pow instead?
public static double Pow(double x, double y)
Returns a specified number raised to the specified power.
See: Math.Pow Method (Double, Double)
You are asking the user to enter something like this: 10Exp3. And you expect your program to raise 10 to the power of 3 and then show the result. So you expect 1000 in this case. But you are simply doing this:
case "Exp":
TB.Text = Math.Exp(Double.Parse(TB.Text) * Math.Log((result) * 4)).ToString();
First issue with your code is, you are using Exp because this is the documentation for Exp:
Returns e raised to the specified power.
Do you want e raised to the specified power? No you do not. So you cannot use that method. But even if you could and wanted to (and maybe you do want e), the computer cannot convert 10Exp3 to a number--you have to tell it what to do.
Here is how (Read my comments inline for more clarity):
var input = "10Exp3";
// Let's split the numbers using <Exp>
var splits = input.Split(new[] { "Exp" }, StringSplitOptions.None);
// Let's try and convert the first part into a double and see if it works
double numberBase = 0;
if (!double.TryParse(splits[0], out numberBase))
{
// The part before the word Exp is
// not a number, perhaps show an error to the user in a message box
}
// Now let's try and convert the second part
double exponent = 0;
if (!double.TryParse(splits[1], out exponent))
{
// The part after the word Exp is
// not a number, perhaps show an error to the user in a message box
}
// Now we will call the Pow method or use Math.Exp if you want e
double result = Math.Pow(numberBase, exponent);
I have knowledge in PHP and I want to learn C # language but I do not even do simple addition.
I want to get the value of a ComboBox, convert this value to int and be able to add another value
Despite the conversion done, I have an error : Can not convert type "int" to "string.
My code :
private void btnValidate_click(object sender, RoutedEventArgs e)
{
int number = Test();
}
int Test()
{
string day = DayBirth.Text;
int number;
bool isNumeric = int.TryParse(day, out number);
if (isNumeric == false)
{
Resultat1.Text = "This is not a number";
}
else
{
Resultat1.Text = number + 10;
}
return number;
}
Thank you
The issue is that Resultat1.Text is expecting a string, not an int. You can do
Resultat1.Text = (number+10).ToString();
and it should work.
what you need to do is Converting your number to string after addition
Resultat1.Text = (number + 10).ToString;
Text property accept string value not integer so after addition you have to convert it as string
Resultat1.Text = (number + 10).ToString();
I have this number in textbox "84,8441546842904" how to convert in 84,8 or 84,84 on button click event?
If by this you mean you want to parse the value and round it to a certain number of decimal places:
double value = Math.Round(double.Parse(textbox.Text), 2);
will parse the text and round it to 2 decimal places. You may need to use a System.Globalization.CultureInfo object when parsing to account for your local culture's number formatting.
See http://msdn.microsoft.com/en-us/library/75ks3aby.aspx
It almost looks like you are trying to trim the number to 1 or 2 precision (isn't the ',' used in some countries as the US '.'?). If this is what you're after, you can use Double.Parse to convert it to a Double and then look into the string format options described here to format it back to the textbox.
I use this kind of functions to validate user input.
This approach to the problem also respects user culture number format!
namespace Your_App_Namespace
{
public static class Globals
{
public static double safeval = 0; // variable to save former value!
public static bool isPositiveNumeric(string strval, System.Globalization.NumberStyles NumberStyle)
// checking if string strval contains positive number in USER CULTURE NUMBER FORMAT!
{
double result;
boolean test;
if (strval.Contains("-")) test = false;
else test = Double.TryParse(strval, NumberStyle, System.Globalization.CultureInfo.CurrentCulture, out result);
// if (test == false) MessageBox.Show("Not positive number!");
return test;
}
public static string numstr2string(string strval, string nofdec)
// conversion from numeric string into string in USER CULTURE NUMBER FORMAT!
// call example numstr2string("12.3456", "0.00") returns "12.34"
{
string retstr = 0.ToString(nofdec);
if (Globals.isPositiveNumeric(strval, System.Globalization.NumberStyles.Number)) retstr = double.Parse(strval).ToString(nofdec);
else retstr = Globals.safeval.ToString(nofdec);
return retstr;
}
public static string number2string(double numval, string nofdec)
// conversion from numeric value into string in USER CULTURE NUMBER FORMAT!
// call example number2string(12.3456, "0.00") returns "12.34"
{
string retstr = 0.ToString(nofdec);
if (Globals.isPositiveNumeric(numval.ToString(), System.Globalization.NumberStyles.Number)) retstr = numval.ToString(nofdec);
else retstr = Globals.safeval.ToString(nofdec);
return retstr;
}
}
// Other Your_App_Namespace content
}
// This is the way how to use those functions
// function to call when TextBox GotFocus
private void textbox_clear(object sender, System.Windows.RoutedEventArgs e)
{
TextBox txtbox = e.OriginalSource as TextBox;
// save original value
Globals.safeval = double.Parse(txtbox.Text);
txtbox.Text = "";
}
// function to call when TextBox LostFocus
private void textbox_change(object sender, System.Windows.RoutedEventArgs e)
{
TextBox txtbox = e.OriginalSource as TextBox;
// text from textbox into sting with checking and string format
txtbox.Text = Globals.numstr2string(txtbox.Text, "0.00");
}
double i = 0;
if (double.TryParse(tbxNumber.Text,out i)) {
MessageBox.Show("number is " + i.ToString());
}