Click here to Skip to main content
15,884,472 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Everything works perfectly fine but I can't seem to output the correct calculations (subtotal, tax, total) for the selected KeyValuePairs in the different comboBox's. Thanks!

What I have tried:

namespace BillCalculator
{
    public partial class Form1 : Form
    {
        double total = 0;
        double subtotal = 0;
        double tax = 0;

        public Form1()
        {
            InitializeComponent();

            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Create a List to store our KeyValuePairs
            List<KeyValuePair<string, double>> data = new List<KeyValuePair<string, double>>();

            //**BEVERAGE**           
            data.Add(new KeyValuePair<string, double>("Select Item", 0.00));
            data.Add(new KeyValuePair<string, double>("Soda", 1.95));
            data.Add(new KeyValuePair<string, double>("Tea", 1.50));
            data.Add(new KeyValuePair<string, double>("Coffee", 1.25));
            data.Add(new KeyValuePair<string, double>("Mineral Water", 2.95));
            data.Add(new KeyValuePair<string, double>("Juice", 2.50));
            data.Add(new KeyValuePair<string, double>("Milk", 1.50));

            // Clear the combobox
            beverageBox.DataSource = null ;
            beverageBox.Items.Clear();

            // Bind the combobox
            beverageBox.DataSource = new BindingSource(data, null);
            beverageBox.DisplayMember = "Key";
            beverageBox.ValueMember = "Value";


            //**APPETIZER**

            
            {
                List<KeyValuePair<string, double>> data1 = new List<KeyValuePair<string, double>>();

                appetizerBox.BindingContext = new BindingContext();

                data1.Add(new KeyValuePair<string, double>("Select Item", 0.00));
                data1.Add(new KeyValuePair<string, double>("Buffalo Wings", 5.95));
                data1.Add(new KeyValuePair<string, double>("Buffalo Fingers", 6.95));
                data1.Add(new KeyValuePair<string, double>("Potato Skins", 8.95));
                data1.Add(new KeyValuePair<string, double>("Nachos", 8.95));
                data1.Add(new KeyValuePair<string, double>("Mushroom Caps", 10.95));
                data1.Add(new KeyValuePair<string, double>("Shrimp Cocktail", 12.95));
                data1.Add(new KeyValuePair<string, double>("Chips and Sala", 6.96));

                // Clear the combobox
                appetizerBox.DataSource = null;
                appetizerBox.Items.Clear();

                // Bind the combobox
                appetizerBox.DataSource = new BindingSource(data1, null);
                appetizerBox.DisplayMember = "Key";
                appetizerBox.ValueMember = "Value";
            }

            //**MAIN COURSE**
            {
                List<KeyValuePair<string, double>> data2 = new List<KeyValuePair<string, double>>();

                mainCBox.BindingContext = new BindingContext();

                data2.Add(new KeyValuePair<string, double>("Select Item", 0.00));
                data2.Add(new KeyValuePair<string, double>("Chicken Alfredo", 13.95));
                data2.Add(new KeyValuePair<string, double>("Chicken Picatta", 13.95));
                data2.Add(new KeyValuePair<string, double>("Turkey Club", 11.95));
                data2.Add(new KeyValuePair<string, double>("Lobster Pie", 19.95));
                data2.Add(new KeyValuePair<string, double>("Prime Rib", 20.95));
                data2.Add(new KeyValuePair<string, double>("Shrimp Scampi", 18.95));
                data2.Add(new KeyValuePair<string, double>("Turkey Dinner", 13.96));
                data2.Add(new KeyValuePair<string, double>("Stuffed Chicken", 14.96));
                data2.Add(new KeyValuePair<string, double>("Seafood Alfredo", 15.96));
                
                // Clear the combobox
                mainCBox.DataSource = null;
                mainCBox.Items.Clear();

                // Bind the combobox
                mainCBox.DataSource = new BindingSource(data2, null);
                mainCBox.DisplayMember = "Key";
                mainCBox.ValueMember = "Value";
            }

            //**DESSERT**
            {
                List<KeyValuePair<string, double>> data3 = new List<KeyValuePair<string, double>>();

                dessertBox.BindingContext = new BindingContext();

                data3.Add(new KeyValuePair<string, double>("Select Item", 0.00));
                data3.Add(new KeyValuePair<string, double>("Apple Pie", 5.95));
                data3.Add(new KeyValuePair<string, double>("Sundae", 3.95));
                data3.Add(new KeyValuePair<string, double>("Carrot Cake", 5.95));
                data3.Add(new KeyValuePair<string, double>("Mud Pie", 4.95));
                data3.Add(new KeyValuePair<string, double>("Apple Crisp", 5.95));
                
                // Clear the combobox
                dessertBox.DataSource = null;
                dessertBox.Items.Clear();

                // Bind the combobox
                dessertBox.DataSource = new BindingSource(data3, null);
                dessertBox.DisplayMember = "Key";
                dessertBox.ValueMember = "Value";
            }
        }
        private void Appetizer_Click(object sender, EventArgs e)
        {

        }
 
  
        private void beverageBox_SelectedIndexChanged(object sender, EventArgs e)
        {
          // Get the selected item in the combobox
    KeyValuePair<string, double> selectedPair = (KeyValuePair<string, double>)beverageBox.SelectedItem;

            // Show selected information on screen
            lblSelectedKey.Text = selectedPair.ToString();
            total = selectedPair.Value;
        }

        private void appetizerBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Get the selected item in the combobox
            KeyValuePair<string, double> selectedPair = (KeyValuePair<string, double>)appetizerBox.SelectedItem;

            // Show selected information on screen
            lblSelectedKey2.Text = selectedPair.ToString();
            total = selectedPair.Value;
        }

        private void mainCBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Get the selected item in the combobox
            KeyValuePair<string, double> selectedPair = (KeyValuePair<string, double>)mainCBox.SelectedItem;

            // Show selected information on screen
            lblSelectedKey3.Text = selectedPair.ToString();
            total = selectedPair.Value;
        }

        private void dessertBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Get the selected item in the combobox
            KeyValuePair<string, double> selectedPair = (KeyValuePair<string, double>)dessertBox.SelectedItem;

            // Show selected information on screen
            lblSelectedKey4.Text = selectedPair.ToString();
            total = selectedPair.Value;
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
           
        }

        private void button1_Click(object sender, EventArgs e)
        {
    

            if (beverageBox.SelectedIndex == 0)
            {
                subtotal = total;
            }
           
            if (appetizerBox.SelectedIndex == 0)
            {
                subtotal = total;
            }

            if (mainCBox.SelectedIndex == 0)
            {
                subtotal = total;                 
            }

            if (dessertBox.SelectedIndex == 0)
            {
                subtotal = total;
            }
           
            textBox1.Text = Convert.ToString(subtotal);
            tax = subtotal * 0.2;
            textBox2.Text = Convert.ToString(tax);
            total = tax + subtotal;
            textBox3.Text = Convert.ToString(total);
        }
    }
 }
Posted
Updated 18-Apr-17 23:45pm
Comments
[no name] 18-Apr-17 19:28pm    
https://www.codeproject.com/Answers/1182257/How-to-remove-duplicate-keys-in-different-combobox#answer1
OfficialSub0 18-Apr-17 20:44pm    
Debugger is showing no syntax errors though. I'm not sure the correct formula, obviously the one I'm using isn't producing the desired results, so I'm sort of confused?
Richard MacCutchan 19-Apr-17 3:00am    
Where is the part that is doing the calculation, and what is wrong with the results.

BTW, using double types for financial calculations is wrong, you will get rounding errors.

1 solution

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 decimalYou 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
C#
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
C#
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
C#
textBox1.Text = Convert.ToString(subtotal);
is really horrible.
C#
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:
C#
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.
C#
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)
    {
        //**BEVERAGE**           
        beverageBox.DataSource = null;
        beverageBox.Items.Clear();
        beverageBox.DataSource = new BindingSource(GetBeverages(), null);
        beverageBox.DisplayMember = "Key";
        beverageBox.ValueMember = "Value";

        //**APPETIZER**
        appetizerBox.DataSource = null;
        appetizerBox.Items.Clear();
        appetizerBox.DataSource = new BindingSource(GetAppetizers(), null);
        appetizerBox.DisplayMember = "Key";
        appetizerBox.ValueMember = "Value";

        //**MAIN COURSE**
        mainCBox.DataSource = null;
        mainCBox.Items.Clear();
        mainCBox.DataSource = new BindingSource(GetMains(), null);
        mainCBox.DisplayMember = "Key";
        mainCBox.ValueMember = "Value";

        //**DESSERT**
        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)
    {
        // Check that something has actually been selected
        if (item == null) return;

        // Get the selected item in the combobox
        var selectedPair = (KeyValuePair<string, decimal>)item;

        // Show selected information on screen
        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)
    {
        //Check 0 if nothign actually selected
        return cb.SelectedIndex != -1 ? ((KeyValuePair<string, decimal>) cb.SelectedItem).Value : 0;
    }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900