Referring to your comment
Quote:
Debugger is showing no syntax errors though
Try to get your terminology right. You cannot debug if you have syntax errors. The
compiler will report syntax (and other) errors. Once you have compiled your program you can run it - debugging is done at runtime and can report exceptions when there are problems with the data or logic. Debugging is what quickly showed me the problem with your code. This article will help you
Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[
^]
You have a number of issues with your code.
1. As @Richard-MacCutchan stated you should not use
double
for financial calculations - see
Decimal vs. Double - difference?[
^] - use
decimal
You will need to either cast the hard-coded values to decimal OR use the suffix
m
to indicate decimal i.e.
data.Add(new KeyValuePair<string, decimal>("Select Item", 0.00m));
2. You are
replacing the value of
total
each time you select an item from one of the ComboBoxes. It is not just a case of adding to total
total += selectedPair.Value;
because you may have previously selected an item from that list. In other words you should not be using the
SelectedIndexChanged
event to add up the total value. The button click event is the correct place to do the adding up. You can probably ignore the rest of my solution as this point will solve your problem, but I urge you to look at all of it.
3. Have a really long look at the code snippet from the button click
if (beverageBox.SelectedIndex == 0)
{
subtotal = total;
}
if (appetizerBox.SelectedIndex == 0)
{
subtotal = total;
}
if (mainCBox.SelectedIndex == 0)
{
subtotal = total;
}
if (dessertBox.SelectedIndex == 0)
{
subtotal = total;
}
You are only setting
subtotal
to the
total
value if the combobox selected item is the very first item "Select Item". So by the time you select everything subtotal is actually 0.
4. The line
textBox1.Text = Convert.ToString(subtotal);
is really horrible.
textBox1.Text = subtotal.ToString();
is much tidier plus you can define the culture you want to use in the call to ToString(). For example, some European countries use a comma instead of a period to indicate a decimal point - this would be determined by the culture setting. So the button click event is getting tidier and currently looks like this:
private void button1_Click(object sender, EventArgs e)
{
if (beverageBox.SelectedIndex != -1)
subtotal += ((KeyValuePair<string, decimal>)beverageBox.SelectedItem).Value;
if (appetizerBox.SelectedIndex != -1)
subtotal += ((KeyValuePair<string, decimal>)appetizerBox.SelectedItem).Value;
if (mainCBox.SelectedIndex != -1)
subtotal += ((KeyValuePair<string, decimal>)mainCBox.SelectedItem).Value;
if (dessertBox.SelectedIndex != -1)
subtotal += ((KeyValuePair<string, decimal>)dessertBox.SelectedItem).Value;
textBox1.Text = subtotal.ToString(CultureInfo.CurrentCulture);
tax = subtotal * (decimal) 0.2;
textBox2.Text = tax.ToString(CultureInfo.CurrentCulture);
total = tax + subtotal;
textBox3.Text = total.ToString(CultureInfo.CurrentCulture);
}
5. You declared the variables
total
,
subtotal
and
tax
at the form level ("global variables"). This was understandable for
total
as you were referring to it all over the place, but for the other two it was not necessary. It is usually considered good practice to declare variables as close as possible to their use, either immediately before the first line to use a variable, OR at the very beginning of the method where they are used.
6. There is quite a lot of what I like to call "almost duplication" of code. Each of the
SelectedIndexChanged
events are very, very similar - it is just the name of the control that is different in each case. I would probably put all of the common stuff in a single method and call that.
Here is my revised version of your code. Note I've moved the code that populates the ComboBoxes into a separate method - to separate the display of information from the retrieval of data - it will make it easier to move to a n-tier form.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private static List<KeyValuePair<string, decimal>> GetBeverages()
{
return new List<KeyValuePair<string, decimal>>
{
new KeyValuePair<string, decimal>("Select Item", 0.00m),
new KeyValuePair<string, decimal>("Soda", 1.95m),
new KeyValuePair<string, decimal>("Tea", 1.50m),
new KeyValuePair<string, decimal>("Coffee", 1.25m),
new KeyValuePair<string, decimal>("Mineral Water", 2.95m),
new KeyValuePair<string, decimal>("Juice", 2.50m),
new KeyValuePair<string, decimal>("Milk", 1.50m)
};
}
private static List<KeyValuePair<string, decimal>> GetAppetizers()
{
return new List<KeyValuePair<string, decimal>>
{
new KeyValuePair<string, decimal>("Select Item", 0.00m),
new KeyValuePair<string, decimal>("Buffalo Wings", 5.95m),
new KeyValuePair<string, decimal>("Buffalo Fingers", 6.95m),
new KeyValuePair<string, decimal>("Potato Skins", 8.95m),
new KeyValuePair<string, decimal>("Nachos", 8.95m),
new KeyValuePair<string, decimal>("Mushroom Caps", 10.95m),
new KeyValuePair<string, decimal>("Shrimp Cocktail", 12.95m),
new KeyValuePair<string, decimal>("Chips and Sala", 6.96m)
};
}
private static List<KeyValuePair<string, decimal>> GetMains()
{
return new List<KeyValuePair<string, decimal>>
{
new KeyValuePair<string, decimal>("Select Item", 0.00m),
new KeyValuePair<string, decimal>("Chicken Alfredo", 13.95m),
new KeyValuePair<string, decimal>("Chicken Picatta", 13.95m),
new KeyValuePair<string, decimal>("Turkey Club", 11.95m),
new KeyValuePair<string, decimal>("Lobster Pie", 19.95m),
new KeyValuePair<string, decimal>("Prime Rib", 20.95m),
new KeyValuePair<string, decimal>("Shrimp Scampi", 18.95m),
new KeyValuePair<string, decimal>("Turkey Dinner", 13.96m),
new KeyValuePair<string, decimal>("Stuffed Chicken", 14.96m),
new KeyValuePair<string, decimal>("Seafood Alfredo", 15.96m)
};
}
private static List<KeyValuePair<string, decimal>> GetDesserts()
{
return new List<KeyValuePair<string, decimal>>
{
new KeyValuePair<string, decimal>("Select Item", 0.00m),
new KeyValuePair<string, decimal>("Apple Pie", 5.95m),
new KeyValuePair<string, decimal>("Sundae", 3.95m),
new KeyValuePair<string, decimal>("Carrot Cake", 5.95m),
new KeyValuePair<string, decimal>("Mud Pie", 4.95m),
new KeyValuePair<string, decimal>("Apple Crisp", 5.95m)
};
}
private void Form1_Load(object sender, EventArgs e)
{
beverageBox.DataSource = null;
beverageBox.Items.Clear();
beverageBox.DataSource = new BindingSource(GetBeverages(), null);
beverageBox.DisplayMember = "Key";
beverageBox.ValueMember = "Value";
appetizerBox.DataSource = null;
appetizerBox.Items.Clear();
appetizerBox.DataSource = new BindingSource(GetAppetizers(), null);
appetizerBox.DisplayMember = "Key";
appetizerBox.ValueMember = "Value";
mainCBox.DataSource = null;
mainCBox.Items.Clear();
mainCBox.DataSource = new BindingSource(GetMains(), null);
mainCBox.DisplayMember = "Key";
mainCBox.ValueMember = "Value";
dessertBox.DataSource = null;
dessertBox.Items.Clear();
dessertBox.DataSource = new BindingSource(GetDesserts(), null);
dessertBox.DisplayMember = "Key";
dessertBox.ValueMember = "Value";
}
private static void ShowSelected(object item, Control label)
{
if (item == null) return;
var selectedPair = (KeyValuePair<string, decimal>)item;
label.Text = selectedPair.ToString();
}
private void beverageBox_SelectedIndexChanged(object sender, EventArgs e)
{
ShowSelected(beverageBox.SelectedItem, lblSelectedKey);
}
private void appetizerBox_SelectedIndexChanged(object sender, EventArgs e)
{
ShowSelected(appetizerBox.SelectedItem, lblSelectedKey2);
}
private void mainCBox_SelectedIndexChanged(object sender, EventArgs e)
{
ShowSelected(mainCBox.SelectedItem, lblSelectedKey3);
}
private void dessertBox_SelectedIndexChanged(object sender, EventArgs e)
{
ShowSelected(dessertBox.SelectedItem, lblSelectedKey4);
}
private void button1_Click(object sender, EventArgs e)
{
var subtotal = AddToTotal(beverageBox);
subtotal += AddToTotal(appetizerBox);
subtotal += AddToTotal(mainCBox);
subtotal += AddToTotal(dessertBox);
textBox1.Text = subtotal.ToString(CultureInfo.CurrentCulture);
var tax = subtotal * (decimal) 0.2;
textBox2.Text = (subtotal * (decimal)0.2).ToString(CultureInfo.CurrentCulture);
textBox3.Text = (tax + subtotal).ToString(CultureInfo.CurrentCulture);
}
private decimal AddToTotal(ComboBox cb)
{
return cb.SelectedIndex != -1 ? ((KeyValuePair<string, decimal>) cb.SelectedItem).Value : 0;
}
}