Как получить возвращаемое значение из события нажатия кнопки? - PullRequest
3 голосов
/ 11 марта 2012

Я только начал изучать C #.Я видел старый вопрос о ком-то, кто пытался сделать кока-колу, и это казалось хорошим упражнением.

Но я застрял на кнопках с деньгами.Я не могу понять, как я могу хранить сумму денег, которую кнопка представляет в переменной, доступной методом ColaMachine.

У меня есть следующий код:

using System;
using System.Windows.Forms;
using System.Drawing;

namespace QuickSharp
{
    public class ColaMachine : Form
    {
        public ColaMachine()
        {
            this.Text = "Cola Machine";
            this.Size = new Size(450 , 500);

            //Money & Money Buttons   

            Label Money;
            Money = new Label();
            Money.Text = "Insert Coins Here:";
            Money.Location = new Point(20, 100);
            this.Controls.Add(Money);

            Button MoneyButton1;
            MoneyButton1 = new Button();
            MoneyButton1.Text = "€0,05";
            MoneyButton1.Location = new Point(28,125);
            MoneyButton1.Click += new System.EventHandler(this.MoneyButton1_Click);
            this.Controls.Add(MoneyButton1);

            Button MoneyButton2;
            MoneyButton2 = new Button();
            MoneyButton2.Text = "€0,10";
            MoneyButton2.Location = new Point(28,165);
            MoneyButton2.Click += new System.EventHandler(this.MoneyButton2_Click);
            this.Controls.Add(MoneyButton2);

            Button MoneyButton3;
            MoneyButton3 = new Button();
            MoneyButton3.Text = "€0,20";
            MoneyButton3.Location = new Point(28,205);
            MoneyButton3.Click += new System.EventHandler(this.MoneyButton3_Click);
            this.Controls.Add(MoneyButton3);

            Button MoneyButton4;
            MoneyButton4 = new Button();
            MoneyButton4.Text = "€0,50";
            MoneyButton4.Location = new Point(28,245);
            MoneyButton4.Click += new System.EventHandler(this.MoneyButton4_Click);
            this.Controls.Add(MoneyButton4);

            Button MoneyButton5;
            MoneyButton5 = new Button();
            MoneyButton5.Text = "€1,00";
            MoneyButton5.Location = new Point(28,285);
            MoneyButton5.Click += new System.EventHandler(this.MoneyButton5_Click);
            this.Controls.Add(MoneyButton5);

            Button MoneyButton6;
            MoneyButton6 = new Button();
            MoneyButton6.Text = "€2,00";
            MoneyButton6.Location = new Point(28,325);
            MoneyButton6.Click += new System.EventHandler(this.MoneyButton6_Click);
            this.Controls.Add(MoneyButton6);

            // Drinks & Drink Buttons

            Label Drinks;
            Drinks = new Label();
            Drinks.Text = "Choose Your Drink:";
            Drinks.Location = new Point(315 , 100);
            Drinks.AutoSize = true;
            this.Controls.Add(Drinks);

            Button DrinkButton1;
            DrinkButton1 = new Button();
            DrinkButton1.Text = "Coca-Cola";
            DrinkButton1.Location = new Point(328,125);
            this.Controls.Add(DrinkButton1);

                        Button DrinkButton2;
            DrinkButton2 = new Button();
            DrinkButton2.Text = "Coca-Cola Light";
            DrinkButton2.Location = new Point(328,165);
            this.Controls.Add(DrinkButton2);

                        Button DrinkButton3;
            DrinkButton3 = new Button();
            DrinkButton3.Text = "Fanta";
            DrinkButton3.Location = new Point(328,205);
            this.Controls.Add(DrinkButton3);

                        Button DrinkButton4;
            DrinkButton4 = new Button();
            DrinkButton4.Text = "Sprite";
            DrinkButton4.Location = new Point(328,245);
            this.Controls.Add(DrinkButton4);

                        Button DrinkButton5;
            DrinkButton5 = new Button();
            DrinkButton5.Text = "Spa Blauw";
            DrinkButton5.Location = new Point(328,285);
            this.Controls.Add(DrinkButton5);

                        Button DrinkButton6;
            DrinkButton6 = new Button();
            DrinkButton6.Text = "Red Bull";
            DrinkButton6.Location = new Point(328,325);
            this.Controls.Add(DrinkButton6);

            //Header & Machine Display

            Label Header;
            Header = new Label();
            Header.Text = "Coca-Cola Machine";
            Header.Font = new Font("Arial" , Header.Font.Size +5);
            Header.ForeColor = Color.DarkRed;
            Header.Location = new Point(132, 20);
            Header.AutoSize = true;
            this.Controls.Add(Header);



            TextBox TextBox1 ;
            TextBox1 = new TextBox();

            if(InsertedCoins == 0.00)
                TextBox1.Text = "Buy Your Ice Cold Drinks Here!";
            else
                TextBox1.Text = "Inserted Coins: €" + InsertedCoins;

            TextBox1.BackColor = Color.Black;
            TextBox1.ForeColor = Color.Red;
            TextBox1.Font = new Font("Arial" , TextBox1.Font.Size +3);
            TextBox1.ReadOnly = true;
            TextBox1.Size = new Size(210,300);
            TextBox1.Location = new Point(112,50);

            // I tried to get the text scrolling here... :)
            TextBox1.SelectionStart = TextBox1.Text.Length;
            TextBox1.ScrollToCaret();
            TextBox1.Refresh();

            this.Controls.Add(TextBox1);
        }


        public double InsertedCoins;

        // Money Button Click Events

        private void MoneyButton1_Click(object sender, EventArgs e)
        {
            InsertedCoins = InsertedCoins + 0.05;
        }

        private void MoneyButton2_Click(object sender, EventArgs e)
        {
            InsertedCoins = InsertedCoins + 0.10;
        }

        private void MoneyButton3_Click(object sender, EventArgs e)
        {
            InsertedCoins = InsertedCoins + 0.20;
        }

        private void MoneyButton4_Click(object sender, EventArgs e)
        {
            InsertedCoins = InsertedCoins + 0.50;
        }

        private void MoneyButton5_Click(object sender, EventArgs e)
        {
            InsertedCoins = InsertedCoins + 1.00;
        }

        private void MoneyButton6_Click(object sender, EventArgs e)
        {
            InsertedCoins = InsertedCoins + 2.00;
        }

        private static void Main()
        {

            ColaMachine Scherm;
            Scherm = new ColaMachine();
            Application.Run(Scherm);
        }
    }
}

Кроме того, если у вас есть какие-либо советы по моему общему программированию (например, чтобы облегчить понимание тем, кто пытается прочитать мой код), пожалуйста, скажите мне!

Ответы [ 3 ]

6 голосов
/ 11 марта 2012

Когда я думаю о машине для кока-колы, я вижу кнопку для каждого типа напитка в машине, но не кнопки для разных сумм денег.Возможно, вы имеете в виду, что кокс стоит 50 центов, поэтому при нажатии на кнопку кокса мне нужно заряжать 50 центов.

Кнопки и обработчики событий

Когда вы нажимаете кнопку на экранеон генерирует событие клика .Вам нужно написать метод, чтобы ответить на этот клик.Любой метод, который мы используем для ответа на событие (вообще говоря), называется обработчиком события .Вы должны сообщить своей программе, какие кнопки идут с какими обработчиками событий.Мы называем это регистрация обработчика события

По соглашению, если ваша кнопка называется CokeButton, то обработчик события, связанный с этой конкретной кнопкой, будет называться CokeButton_ClickHandler.Или что-то в этом роде.

Общие советы

Подумайте о том, что вы моделируете, и определите вещи в коде, чтобы они отражали реальный мир. вещи в вашей модели обычно заканчиваются как классы, свойства класса и поля класса.То, что эти вещи делают, обычно заканчиваются методами в соответствующем классе.Затем вы думаете о том, как эти вещи взаимодействуют.

Вам не нужно выяснять всего о коксовой машине, прежде чем вы начнете писать код.И вы должны писать маленькие кусочки за раз, проверять их, а затем опираться на то, что вы проверяли.Не пишите кучу сложного кода, а затем тестируйте.Вы будете вращаться кругами, преследуя свой хвост.Напишите немного, немного попробуйте, повторите. Услышь меня сейчас и поверь мне позже;Пиши немного, тестируй немного, повторяй. Прислушайся к этому совету сейчас и навсегда.

Так вот как я могу подумать о кока-коле.Сначала есть сама кока-машина.

public class CokeMachine {}

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

Но мне нужно знать, сколько стоит каждый напиток.

Ладно, хорошо.тогда должны быть поля "CokeCost", "7UpCost" и т. д.Так определите их!Мы выясним, как и где их использовать, по мере продвижения.

   public class CokeMachine {
     Button Coke;
     Button 7Up;
     Button RootBeer;
     TextBox MoneySlot;

     double CokeCost = .75;
     double 7UpCost = .65;
}

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

   public class CokeMachine {
     Button Coke;
     Button 7Up;
     Button RootBeer;
     TextBox MoneySlot;

     double CokeCost = .75;
     double 7UpCost = .65;

     // "wiring up" the coke button click event to it's handler.
     // We do this in C# by declaring an new EventHandler object (a .NET framework supplied class)
     // and we pass in the name of our method as a parameter.
     // This new EventHandler is *added* to the button's click event.
     // An event can have multiple handlers, that's why we do "+="
     // instead of just "=". Otherwise we would have accidentally "unhooked" any
     // previously registered handlers.
     Coke.Click += new EventHandler(Coke_ClickHandler);

     // this is the .NET event handler method signature.
     Public void Coke_ClickHandler (object sender, EventArgs args){
          if (MoneySlot.Value >= CokeCost) {
             DispenseDrink();
             // How do I handle returning change? Maybe DispenseDrink() can do that.
          }else {
             // tell customer to put in more money
          }
     }

     private void DispenseDrink() {
       // An empty method is enough to get it to compile so for now that's fine.
       // I need to test the Coke_EventHandler logic that I've written so far.
     }

  }

Теперь мне нужно проверить то, что я написал до сих пор.После этого мне нужно решить, на чем сосредоточиться дальше.Но поймите, что когда вы пишете новый код, который зависит от уже написанного кода, если этот существующий код не был протестирован - и теперь вы видите ошибки, вы только что сделали это намного сложнее для себя.Вы могли бы проверить, когда код проще.Теперь есть еще кое-что, более сложное, и его будет сложнее отлаживать и исправлять.

Предложения, Часть II

На риск все испортится, я предлагаю этоДалее к моему первоначальному ответу:

Вы можете видеть, что каждая кнопка напитка делает одно и то же, и, учитывая приведенный выше код, мы будем писать одну и ту же логику снова и снова для каждой кнопки.Если что-то должно измениться, мы должны изменить это везде.

Дополнительные общие рекомендации

Одна объектно-ориентированная эвристика прогамминга инкапсулирует то, что остается прежним .Вы всегда должны быть в поисках мест, где вещи могут быть кандидатами в общий код.

Я хочу подчеркнуть, что это обычное поведение кнопок не было для меня сразу очевидным. Только после того, как я написал приведенный выше код, я подумал, что все мои обработчики кнопок для напитков будут выглядеть одинаково, и я понял, что на реальной машине для напитков они действительно ведут себя одинаково. Мой смысл в коде сказал, что это хорошо, когда код отражает идентифицируемое поведение вашей реальной вещи (каламбур!).

Рефакторинг

На самом деле это технический термин, который означает переработку существующего кода, чтобы сделать его более гибким, многократно используемым, читаемым и т. Д. Одним словом ремонтопригоден.

Рефакторинг должен постоянно находиться в ваших мыслительных процессах. Но убедитесь, что у вас есть законная причина для каких-либо изменений. Изменение кода является нормальной, неотъемлемой частью разработки программного обеспечения.

Давайте рефакторинг путем извлечения метода

     Public void Coke_ClickHandler (object sender, EventArgs args){
          PurchaseDrink("Coke", CokeCost);
     }

     // now we have a method that stands out and says THIS is how it works
     // and a single point of change, rather than ump-teen button handlers.
      private PurchaseDrink (string whatKind, double cost) {

         // all I did so far is move the code and change "Cokecost" to "cost"
         // Now I'm beginning to think I may need to pass "whatKind" to
         // DispenseDrink() - but first I need to test the changes I've
         // made at this level.
         // ***** and since I already tested the code when I 1st wrote it,
         // this refactoring will be easier & quicker to test.. GET IT??!! ******

         if (MoneySlot.Value >= cost) {
             DispenseDrink();
             // How do I handle returning change? Maybe DispenseDrink() can do that.
          }else {
             // tell customer to put in more money
          }
     }

     private void DispenseDrink() {
       // An empty method is enough to get it to compile so for now that's fine.
       // I need to test the Coke_EventHandler logic that I've written so far.
     }

Перечисления

Я ненавижу использовать строки, как я использовал "Кокс" выше. Опечатки и регистр (то есть верхний / нижний) могут вызвать проблемы, которые Visual Studio не поймает. Когда у меня есть ограниченный список вещей - виды напитков - я действительно люблю использовать перечисления. Они обнаруживаются в интеллектуальном смысле, и я могу использовать их в выражениях переключателя (и исследовать идею «безопасного типа»). И что мне действительно нравится, так это то, что они абсолютно определяют в одном месте все типы напитков, о которых знает наша программа. Это как документация!

3 голосов
/ 11 марта 2012

Вы можете сохранить сумму для каждого свойства тега кнопки i button и использовать следующий код в обработчике событий для считывания суммы:

void ValueButton_Click(object sender, EventArgs e)
{
  Button button = sender as Button;
  if (button == null) return;
  if (button.Tag == null) return;
  double amount = (double)button.Tag;

  // Process the amount here....
  InsertedCoins += amount; 
}
0 голосов
/ 11 марта 2012

Сначала подумайте : Вы должны разделить задачу на два класса (класс Test и класс ColaMachine).

Это выглядит как

public class ColaMachine : Form
{
  public ColaMachine()
  {  
     ...
  }
}

public class Test 
{
   private static void Main()
   {
      ColaMachine Scherm;
      Scherm = new ColaMachine();
      Application.Run(Scherm);
   }
}

Следующее : Если вы хотите вернуть переменную private , используйте properties .IC будет публичный метод (свойства).InsertedCoins будет закрытой переменной.

public double IC
{
   get
   {
      return InsertedCoins;
    }
   set
   {
      InsertedCoins = value;
   }
}

Не забывайте, что на машине много состояний .Вы должны использовать дизайн Pattern, в точности State pattern .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...