0

场景:
我想点击一个文本块并运行一个方法将该项目添加到购物车。
不,我不喜欢按钮而不是文本块,谢谢 :)

代码 (shoppingcart.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;

namespace m_POS
{
    public class shoppingcart
    {
        int cartnum;
        int duplicate=0;
        int num_of_items;
        int counter=1;
        List<item> items = new List<item>();

        //constructor
        public shoppingcart()
        {
            this.cartnum = counter;
            counter += 1;
            this.num_of_items = 0;
            this.items = new List<item>();
            init_items();
        }

        //return the item list of tapped/purchased items
        public List<item> getitems(){
            return this.items;
        }

        //returns the number of items tapped/purchased
        public int get_num_of_items() { return this.num_of_items; }

        // the method that adds a tapped-on item to the items list
        public void additem(String itemx,String qty) {


            for (int i = 0; i < item.pick_item.Count; i++)
            {
                if (itemx.Equals(item.pick_item[i].getname()))
                {
                    item itm = new item(item.pick_item[i].getname(), 
                    item.pick_item[i].getprice());
                    itm.addqty(Convert.ToInt16(qty));
                    this.items.Add(itm);
                    Debug.WriteLine("added to cart!!");
                }
            }

                this.num_of_items += Convert.ToInt16(qty);
        }

//used to test the additem() works. Everytime the class is run, this Rolex item will
  //be the first to be added to the cart. ALWAYS. Funny thing is, it doesnt get
  // duplicated.
        private void init_items()
        {
            item itm12 = new item("Rolex", 4000);
            //additem(itm12);
            this.items.Add(itm12);
        }


    }

////////////////////////////////////////////////////////////////////////////////////////

    public class item
    {
        String itemname;
        int itemamount;
        int itemqty = 0;

        public static List<item> pick_item = new List<item>();

        public static List<String> menu_food = new List<string> {
        "Single Beef Burger",
           "Double Beef Burger",
           "Triple Beef Burger",
           "Single Chicken Burger",
           "Double Chicken Burger",
           "Single Veggie Burger",
           "1/2 Fries",
           "Full Fries",
           "Beef Steak",
            "Mushroom",
            "Steamed Rice",
            "Rolex"};

        public static List<String> menu_price = new List<String>{
            "8000",
            "17000",
            "25000",
            "12000",
            "26500",
            "7500",
            "4000",
            "6000",
            "20000",
            "25000",
            "17500",
            "4000"};

        public item(string name, int amount)
        {
            this.itemamount = amount;
            this.itemname = name;
            this.itemqty = 1;
        }

        public static void init_menu()
        {
            for (int i = 0; i < get_menu().Count; i++)
            {
                item itm = new item(menu_food[i], Convert.ToInt32(menu_price[i]));
                pick_item.Add(itm);
            }
        }

        public void addqty(int qty) { this.itemqty = qty; }

        public string getname() { return this.itemname; }

        public int getprice() { return this.itemamount; }

        public static int getpxbyname(string itemname) {
            int ans=0;
            for (int y = 0; y < pick_item.Count; y++) {
                if (pick_item[y].itemname.ToString().Equals(itemname)) {
                    ans = pick_item[y].itemamount;
                }
            }
            return ans;
        }

        public static List<String> get_menu() { return menu_food; }

        public static List<String> get_price() { return menu_price; }


    }

}

重复发生在哪里?
我得到 additem(string itemname,int itemqty)在每次点击时运行两次。不过,其他一切都很完美。

发帖前我做了什么?
- 测试了Tap事件并确保它每次点击只被触发一次?查看。
- 测试了该additem()方法以确保它可以使用?查看。每次启动应用程序时,我都会在购物车中添加一个项目。该项目永远不会被复制。

控制台 Debug.WriteLine() 显示

added to cart!!
added to cart!!
called method with System.Windows.Controls.TextBlock

前两个added to cart来自被调用两次的方法。
下一个来自我在从Food.xaml.cs [部分]called method with System.Windows.Controls.TextBlock调用此方法后插入的调试Food.xaml.cs

    public Foods()
    {
        InitializeComponent();
        item.init_menu();
        populatemenu();

    }

    public void populatemenu()
    {

        List<String> display = item.get_menu();
        for (int i = 0; i < display.Count; i++)
        {
            string tname = "tb" + i;
            TextBlock tb = new TextBlock();
            tb.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(tb_Click);
            tb.Style = (Style)Resources["textblocker"];
            tb.FontSize = 36;
            tb.Text = display[i];
            tb.Name = tname;
            sp_lunch.Children.Add(tb);

        }
    }
    private void tb_Click(object sender, RoutedEventArgs e)
    {
        tapped += 1;
        selectqty(sender);
    }

    private void selectqty(object sender) {
        Popup popup = new Popup();
        popup.Height = 300;
        popup.Width = 400;
        popup.VerticalOffset = 100;
        PopUpControl control = new PopUpControl();
        popup.Child = control;
        popup.IsOpen = true;
        string qty="";


        control.btnOK.Click += (s, args) =>
            {
                popup.IsOpen = false;
                //pick input from the popup's textbox.
                qty = control.tbx.Text;
                if (qty == null||qty=="") { qty = "0"; }

                //send clicked item to cart for addition
                TextBlock clicked = ((TextBlock)sender);
                string temp = clicked.Text;
                Cart.cart_new.additem(temp, qty);
                Debug.WriteLine("called method with "+sender.ToString());
                tb_pamount_lunch.Text = Convert.ToString(Cart.cart_new.get_num_of_items());
                //tb_pamount_lunch.Text = tapped.ToString();
                MessageBox.Show(temp);

                //update the dinner stackpanel to display the selected items
                sp_dinner.Children.Clear();
                List<item> display = Cart.cart_new.getitems();
                for (int i = 0; i < display.Count; i++)
                {
                    TextBlock tb1 = new TextBlock();
                    tb1.FontSize = 36;
                    tb1.Text = display[i].getname().ToString();
                    sp_dinner.Children.Add(tb1);
                }

            };
        control.btnCancel.Click += (s, args) =>
            {
                //close popup when cancel is clicked
                popup.IsOpen = false;
            };
    }


还有更多信息吗??
如果您还想看其他课程,我很乐意在此处复制/粘贴或上传整个 project.zip :)

4

1 回答 1

0

我想当你第三次点击标签时,将添加 3 个项目。

(s, args) =>
        {
            popup.IsOpen = false;
            //pick input from the popup's textbox.
            qty = control.tbx.Text;
            if (qty == null||qty=="") { qty = "0"; }

            //send clicked item to cart for addition
            TextBlock clicked = ((TextBlock)sender);
            string temp = clicked.Text;
            Cart.cart_new.additem(temp, qty);
            Debug.WriteLine("called method with "+sender.ToString());
            tb_pamount_lunch.Text = Convert.ToString(Cart.cart_new.get_num_of_items());
            //tb_pamount_lunch.Text = tapped.ToString();
            MessageBox.Show(temp);

            //update the dinner stackpanel to display the selected items
            sp_dinner.Children.Clear();
            List<item> display = Cart.cart_new.getitems();
            for (int i = 0; i < display.Count; i++)
            {
                TextBlock tb1 = new TextBlock();
                tb1.FontSize = 36;
                tb1.Text = display[i].getname().ToString();
                sp_dinner.Children.Add(tb1);
            }

        };
    control.btnCancel.Click += (s, args) =>
        {
            //close popup when cancel is clicked
            popup.IsOpen = false;
        };

这是因为控件仍然存在,并且每次调用selectqty时都会将另一个操作添加到事件处理程序列表中。并且将被执行的不止一个。您应该只注册事件。就像在你的构造函数中一样。

个人:您应该将事件注册到子控件内的按钮。而是在控件上创建一个新事件并在那里引发它。这将使您能够在不更改主窗体的情况下更改该控件上的按钮或其他控件(也许您将来需要快捷键)。

例子:

public class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        control.btnOKClicked += Control_buttonOk;
        control.btnCancelClicked += Control_buttonCancel;
    }

    private void Control_buttonOk(object sender, eventArgs e)
    {
        // implement code
    }

    private void Control_buttonCancel(object sender, eventArgs e)
    {
        // implement code
    }
}

public class UserControl1: UserControl
{
    public UserControl1()
    {
        InitializeComponent();
        btnOK.Click += (sender, e) =>
        {
            if(btnOKClicked != null)
                btnOKClicked(this, EventArgs.Empty);
        };
        btnCancel.Click += (sender, e) =>
        {
            if(btnCancelClicked!= null)
                btnCancelClicked(this, EventArgs.Empty);
        };
    }

    public event EventHandler btnOKClicked;
    public event EventHandler btnCancelClicked;
}

通过这种方式,您可以分离控件布局的功能/依赖关系。

在我写这篇文章的时候,我想你可以看看这里: Form.ShowDialog Method http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx这将处理 popup.IsOpen 并阻止你的 MainForm 直到它关门了。使用 DialogResult 您可以读取用户是否按下了确定或取消。

于 2013-08-28T10:31:31.343 回答