如何从按钮单击事件中获取返回值? [英] How do I get a return value from a Button Click event?

查看:68
本文介绍了如何从按钮单击事件中获取返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习 C#.我看到有人试图制作可口可乐机的老问题,这似乎是一个很好的练习.

I just started learning C#. I saw an old question of someone trying to make a coca-cola machine and it seemed like a good exercise.

但是我卡在了钱按钮上.我不知道如何将按钮代表的金额存储在可通过 ColaMachine 方法访问的变量中.

But I got stuck on the money buttons. I can't figure out how I can store the amount of money a button represents in a variable, accessible by the ColaMachine method.

我有以下代码:

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

另外,如果您对我的一般编程有任何建议(例如,让其他人更容易阅读我的代码),请告诉我!

Also, if you have any tips on my general programming (e.g. to make things easier-to-follow for others trying to read my code), please tell me!

推荐答案

当我想到可乐机时,我看到机器中每种饮料都有一个按钮,但没有看到不同金额的按钮.也许你的意思是可乐要 50 美分,所以按下可乐按钮我需要收费 50 美分.

When I think about a Coke machine I see a button for each type of drink in the machine, but not buttons for different amounts of money. Maybe you mean a coke costs 50 cents so pressing the coke button I need to charge 50 cents.

按钮和事件处理程序

当您按下屏幕上的按钮时,它会生成一个点击事件.您需要编写一个方法来响应该点击.我们用来响应事件(一般来说)的任何方法都称为事件处理程序.您必须告诉您的程序哪些按钮与哪些事件处理程序对应.我们称之为注册事件处理程序

When you press a button on the screen it generates a click event. You need to write a method to respond to that click. Any method that we use to respond to an event (generally speaking) is called an event handler. You must tell your program what buttons go with what event handlers. We call this registering the event handler

按照惯例,如果您的按钮命名为CokeButton",那么与该特定按钮关联的事件处理程序将命名为CokeButton_ClickHandler".或者类似的东西.

By convention, if your button is named 'CokeButton' then the event handler associated with that specific button would be named 'CokeButton_ClickHandler'. Or something like that.

一般建议

考虑您正在建模的事物并在代码中定义事物以反映现实世界.模型中的事物通常最终会成为类、类属性和类字段.这些事情所做的通常最终会成为具有适当类的方法.然后你会考虑这些东西是如何相互作用的.

Think about the thing you are modeling and define things in code to reflect the real world. The things in your model typically will end up as classes, class properties, and class fields. What these things do typically end up as methods w/in the appropriate class. Then you think about how these things interact.

在开始编写代码之前,您无需弄清楚关于可乐机的一切.你应该一次写一点,测试它们,然后建立在你测试过的基础上.不要编写大量复杂的交互代码,然后进行测试.你最终会绕着圈子追着你的尾巴旋转.写一点,测试一点,重复.现在听我说,以后相信我;写一点,测试一点,重复.现在和永远注意这个建议.

You do not need to figure out everything about a coke machine before you begin writing code. And you should write little bits at a time, test those and then build on what you've tested. Do not write oodles of complex-ish interacting code and then test. You'll end up spinning in circles chasing your tail. Write a little, test a little, repeat. Hear me now and believe me later; write a little, test a little, repeat. Heed this advice now and forever.

这就是我对可乐机的看法.首先是焦炭机本身.

So here's how I might think about a Coke Machine. First there is a coke machine itself.

public class CokeMachine {}

可乐机有一个钱槽、一个退货槽和一个饮料按钮.我真的不能把钱放在一个插槽里,所以暂时,我会说我会在一个文本框中输入.然后我会点击一个按钮,可乐就会被分配出来.我觉得我已经定义了足够多的模型来开始.可乐机还有很多其他的东西,但我现在不会担心.

A coke machine has a money slot, a return slot, and drink buttons. I can't really put money in a slot, so off hand, I'd say I'll type into a text box. Then I'll click a button and the coke will dispense. I feel like I've defined enough of the model to get started. There's lots of other things about a Coke Machine but I'm not going to worry about them right now.

但我需要知道每杯饮料的价格.

嗯,好的.那么必须有CokeCost"、7UpCost"等字段.所以定义它们!随着我们的进展,我们将弄清楚如何以及在何处使用它们.

Well, OK. then there must be "CokeCost", "7UpCost", etc. fields. So define them! We'll figure out how and where to use them as we go along.

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

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

我说过按钮需要处理程序,所以我们至少可以编写一些代码外壳.我希望它们都以相同的方式工作,所以我现在将专注于一个.请注意,当我编写代码时,我意识到必须处理其他事情.我会添加注释,调用尚不存在的方法等.

I said the buttons need handlers, so we can write some code shells at least. I expect they'll all work the same way so I'll focus on one for now. Note that as I write code I realize other things that must be dealt with. I'll put in comments, calls to methods that don't exist yet, etc.

   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.
     }

  }

现在我需要测试我到目前为止所写的内容.在那之后,我需要决定接下来要关注什么.但是要意识到,当您编写依赖于已编写代码的新代码时,如果现有代码尚未经过测试 - 现在您看到错误,您只是让自己变得更难了.当代码更简单时,您可以进行测试.现在有更多,更复杂,更难调试和修复.

Now I need to test what I've written so far. After that I need to decide what to focus on next. But realize that when you're writing new code that depends on already written code, if that existing code has not been tested - and now you see errors, you've just made it much harder on yourself. You could have tested when the code is simpler. Now there's more, it's more complex, and will be harder to debug and fix.

建议,第二部分

冒着把事情搞砸的风险,我提供了对原始答案的跟进:

At the risk of messing things up, I offer this folow-up to my original answer:

你可以看到每个饮料按钮都做同样的事情,给定上面的代码,我们将为每个按钮一遍又一遍地编写相同的逻辑.如果有什么需要改变,我们必须到处改变它.

You can see that every drink button does the same thing, and given the above code we would write the same logic over and over for every button. If anything needs to change we have to change it everywhere.

更一般的建议

一个面向对象的编程启发式是封装保持不变的.您应该始终注意可能适合使用通用代码的地方.

One Object Oriented Progamming heuristic is encapsulate that which stays the same. You should always be on the lookout for places where things may be candidates for common code.

我想强调的是,这种常见的按钮行为对我来说并不是很明显.只有在我编写了上面的代码之后,我才开始认为我所有的饮料按钮处理程序看起来都一样,并且我意识到在真正的饮料机器上它们的行为实际上是相同的.我的编码技巧告诉我,当代码反映真实事物的可识别行为时,这绝对是一件好事(双关语!).

I want to emphasize that this common button behavior was not immediately obvious to me. Only after I wrote the code above did I get to thinking that all my drink button handlers would start to look the same and I realized that on a real drink machine they actually do behave the same way. My coding spidey-sense told it definitely is a good thing when the code reflects the identifiable behaviors of your real thing (pun intended!).

重构

实际上是一个技术术语,意思是修改现有代码,使其更加灵活、可重用、可读等.总之,可维护.

Actually is a technical term that means reworking existing code to make it more flexible, re-useable, readable, etc. In a word maintainable.

重构应该一直在你的思维过程中.但请确保您有正当理由进行任何更改.重构代码是软件开发的一个正常的、不可或缺的部分.

Refactoring should be in your thought processes all the time. But be sure you have a legitimate reason for making any change. Reshaping code is a normal, integral part of software development.

让我们通过提取方法

     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 无法发现的问题.当我有一个有限的东西清单时——各种饮料——我真的很喜欢使用枚举.它们出现在智能感知中,我可以在 switch 语句中使用它们(并研究类型安全"的想法).我真正喜欢的是,他们绝对在一个地方定义了我们的程序知道的所有饮料类型.就像文档一样!

I hate using strings the way I used "Coke" above. Typo's and casing (upper/lower, that is) can cause problems that Visual Studio won't catch. When I have a limited list of things - kinds of drinks - I really like using enumerations. They show up in intellesense and I can use them in switch statements (and research the idea of "type safe"). And what I REALLY like is that they absolutely define in one place all the drink types our program knows about. It's like documentation!

这篇关于如何从按钮单击事件中获取返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆