OfficialSub0 Ответов: 1

Как рассчитать выбранные пары ключевых значений combobox?


Все работает отлично, но я не могу вывести правильные вычисления (subtotal, tax, total) для выбранных пар KeyValuePairs в разных comboBox. Спасибо!

Что я уже пробовал:

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);
        }
    }
 }

[no name]

https://www.codeproject.com/Answers/1182257/How-to-remove-duplicate-keys-in-different-combobox#answer1

OfficialSub0

Однако отладчик не показывает никаких синтаксических ошибок. Я не уверен, что правильная формула, очевидно, та, которую я использую, не дает желаемых результатов, поэтому я немного запутался?

Richard MacCutchan

Где находится та часть, которая делает расчет, и что не так с результатами.

Кстати, использование двойных типов для финансовых расчетов неверно, вы получите ошибки округления.

1 Ответов

Рейтинг:
9

CHill60

Ссылаясь на ваш комментарий

Цитата:
Однако отладчик не показывает никаких синтаксических ошибок
Постарайтесь правильно подобрать терминологию. Вы не можете отлаживать, если у вас есть синтаксические ошибки. То компилятор сообщит о синтаксических (и других) ошибках. После того как вы скомпилировали свою программу, вы можете запустить ее - отладка выполняется во время выполнения и может сообщать об исключениях, когда возникают проблемы с данными или логикой. Отладка-это то, что быстро показало мне проблему с вашим кодом. Эта статья поможет вам Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]

У вас есть ряд проблем с вашим кодом.

1. Как заявил @Richard-MacCutchan, вы не должны использовать double для финансовых расчетов-см. Десятичное число против Двойная разница?[^] - использовать decimalВам нужно будет либо привести жестко закодированные значения к десятичной системе счисления, либо использовать суффикс m чтобы указать десятичное число т. е.
data.Add(new KeyValuePair<string, decimal>("Select Item", 0.00m));
2. Вы заменяющий значение total каждый раз, когда вы выбираете элемент из одного из комбо-боксов. Это не просто случай добавления к общей сумме
total += selectedPair.Value;
потому что вы, возможно, ранее выбрали элемент из этого списка. Другими словами, вы не должны использовать SelectedIndexChanged событие для суммирования общей стоимости. Событие нажатия кнопки-это правильное место для сложения. Вы, вероятно, можете проигнорировать остальную часть моего решения, поскольку этот пункт решит вашу проблему, но я настоятельно призываю вас взглянуть на все это.

3. очень долго смотрите на фрагмент кода от нажатия кнопки
if (beverageBox.SelectedIndex == 0)
{
    subtotal = total;
}

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

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

if (dessertBox.SelectedIndex == 0)
{
    subtotal = total;
}
Вы не только subtotal к total значение, если выбранный элемент combobox является самым первым элементом "Select Item". Таким образом, к тому времени, когда вы выберете все, промежуточный итог на самом деле равен 0.

4. Линии
textBox1.Text = Convert.ToString(subtotal);
это действительно ужасно.
textBox1.Text = subtotal.ToString();
это намного опрятнее, плюс вы можете определить культуру, которую хотите использовать в вызове ToString (). Например, некоторые европейские страны используют запятую вместо точки для обозначения десятичной точки - это будет определяться настройками культуры. Таким образом, событие нажатия кнопки становится более аккуратным и в настоящее время выглядит следующим образом:
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. Вы объявили переменные total, subtotal и tax на уровне формы ("глобальные переменные"). Это было понятно для total как вы уже говорили, это было повсюду, но для двух других это не было необходимо. Обычно считается хорошей практикой объявлять переменные как можно ближе к их использованию, либо непосредственно перед первой строкой для использования переменной, либо в самом начале метода, в котором они используются.

6. Существует довольно много того, что я люблю называть "почти дублированием" кода. Каждый из них SelectedIndexChanged события очень, очень похожи - это просто название элемента управления, которое отличается в каждом случае. Я бы, вероятно, поместил все общие вещи в один метод и вызвал его.

Вот моя пересмотренная версия вашего кода. Обратите внимание, что я переместил код, заполняющий комбо-боксы, в отдельный метод - чтобы отделить отображение информации от извлечения данных, - это облегчит переход к n-уровневой форме.
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 selected