C# Winform简单模拟水果店结账系统

简介

现实生活中,结账系统无处不在,屡见不鲜,各种结账系统 例如:订餐结账系统,超市购物结账系统,酒店客房结账系统等等.

其实结账原理都大同小异,即将所有购买项的价格都相加,当然,那些复杂的系统所考虑的方面和功能就很多了,我们这里不考虑.

那么,今天我们这里简单的写个基于 C# winform 平台的水果店结账系统.

 

原理

这里用到了一个主窗体类和一个构造函数类(用于存取物品的属性) 以及一个写有物品属性的文本文件(目的是方便后期更改物品的价格,折扣等属性).

首先,通过FileStream的OpenRead方法来打开并读取文本文件, 然后调用StreamReader类来读取FileStream的字符并将里面的字节转换成字符串.

具体FileStream和StreamReader的用法,可以参考这里. 从文本里获取到物品的属性之后,将其存到一个具有物品属性的数据结构的泛型list里.

然后在各个物品按钮下调用不同物品,每个物品在泛型list里的索引也是不一样的.之后再用一个整型数组来存储每个物品按钮的点击次数,即为每个物品的购买次数.

还用到一个泛型list来装载每个物品的价格,在计算总价的时候遍历并相加, 得到一个总价.

这里还用到了一个优惠价,即每个物品都有不同的打折方式(代码里有详细注释), 用到了一些简单的算法,并且在结账的时候自动计算每项物品最终优惠了多少.

然后用 总价-优惠价=最终我们应该支付的价格,当然这里也实现了物品清空的功能.

 

界面设计

C# Winform简单模拟水果店结账系统

 

fruits.txt文本内容

C# Winform简单模拟水果店结账系统

 

代码如下

ProductAttribute.cs 类里的代码

class ProductAttribute

{

    //初始化各值

    string name = "";

    float price = 0;

    int code1 = 0;

    int code2 = 0;

    //构造方法

    public ProductAttribute(string n, float p, int c1, int c2)

    {

        //实现ProductAttribute的数据结构 

        //里面可以传入如下参数

        name = n;

        price = p;

        code1 = c1;

        code2 = c2;

    }

    //可以读取ProductAttribute里的Name 属性

    public string Name

    {

        get { return name; }

    }

    //可以读取ProductAttribute里的Price 属性

    public float Price

    {

        get { return price; }

    }

    // 一个save方法 用于判断 不同的折扣方式 并返回一个减去的钱数

    public float save(int n)

    {

        float m = 0;  //m用于获取 打折后的 价格 符合的物品数量

        switch (code1)

        {

            case 0: //code1为0 的时候 

                m = n;  //买多少斤 最终价格还是 按多少斤算

                break;

            case 1: //code1为1的时候 有2种情况 

                if (code2 == 0)  //code2为0  买1斤 第2斤免费 即买一送一 

                    m = (float)((n / 2) + (n % 2));  //买1斤 第2斤免费  但买3斤 还是1斤免费 

                else if (code2 == 1) //code2为1  这里是买1斤 第2斤半价 即买2斤 1斤半的钱  买4斤 3斤的钱

                    m = (float)(1.5 * (n / 2) + (n % 2));

                break;

            case 2:   //code1 为2的时候 也有2种方法

                if (code2 == 0)  //code1为2 code2 为0 买2斤 第3斤免费

                    m = (float)(n - (n / 3));

                else if (code2 == 1) //code1为2  code2为1 即买2斤 第3斤半价

                    m = (float)(n - 0.5 * (n / 3));

                break;

        }



        float save = (n - m) * price; //计算出一个最终的价格

        return save;  //返回省去的钱数

    }

}

主窗体类代码 frmFruitShopping.cs

    public partial class frmFruitShopping : Form

    {        

        public frmFruitShopping()

        {

            InitializeComponent();



            this.Load += (s, e) => { ReadFruitsData();  FruitClick(); };

            btnTotal.Click += (s, e) => { GetTotalCost(); };

            btnEmpty.Click += (s, e) => { EmptyShoppingBox(); };

            btnDeleteOne.Click += (s, e) => { DeleteOneShoppingItem(); };

        }



        List<ProductAttribute> productList;



        /// <summary>

        /// 读取txt文本数据

        /// </summary>

        private void ReadFruitsData()

        {

            //创建一个水果属性的集合

            productList = new List<ProductAttribute>();

            string strRead; //创建一个字符串 用来接受读取的数据

            // 创建FileStream文件流 可以用来读取任何文件 其内部读取格式是 最原始的字节

            FileStream fs = File.OpenRead("fruits.txt");

            //通过流读取来读取fs文件里的东西,并将 文字格式设置为默认的ANSI编码

            using (StreamReader sr = new StreamReader(fs, Encoding.Default))

            {

                //用while循环来 一行行读取  如果读到的内容不为空 则进入循环 否则不读

                while ((strRead = sr.ReadLine()) != null)

                {

                    //这里用到了个字符串分割 每行都有几个参数 通过'-' 隔开 分割后存到一个数组里

                    string[] part = strRead.Split('-');

                    //new一个 构造方法来装载 这些参数

                    ProductAttribute pa = new ProductAttribute(part[0], (float)Convert.ToDouble(part[1]), Convert.ToInt32(part[2]), Convert.ToInt32(part[3]));

                    //将 装载的参数 存到水果属性的list集合中

                    productList.Add(pa);

                }

            }

        }



        //创建一个TotalCost集合 来装载 所有的开销

        List<float> TotalCost = new List<float>();

        //定义一个 可以容纳12个整数的整型数组 用于装载 每样产品的点击数

        int[] intQuantity = new int[12];



        /// <summary>

        /// 记录并打印每项水果的花费

        /// </summary>

        /// <param name="i">物品的索引</param>

        public void printCost(int i)

        {

            intQuantity[i]++;

            lstMenu.Items.Add("您购买了\t" + productList[i].Name + "\t " + productList[i].Price + "元/斤");

            TotalCost.Add(productList[i].Price);

        }



        /// <summary>

        /// 实现所有水果按钮单击事件下触发的打印花费的方法

        /// </summary>

        private void FruitClick()

        {

            //每个按钮下 都调用了一个 printCost();方法 

            //传入的整型参数 是购物品在TotalCost集合里的位置 同时也是intQuantity的索引位置

            btnApple.Click += (s, e) => { printCost(0); };

            btnOrange.Click += (s, e) => { printCost(1); };

            btnPear.Click += (s, e) => { printCost(2); };

            btnbanana.Click += (s, e) => { printCost(3); };

            btnHawthorn.Click += (s, e) => { printCost(4); };

            btnHoneyPeach.Click += (s, e) => { printCost(5); };

            btnCoconut.Click += (s, e) => { printCost(6); };

            btnFig.Click += (s, e) => { printCost(7); };

            btnGrape.Click += (s, e) => { printCost(8); };

            btnLitchi.Click += (s, e) => { printCost(9); };

            btnPlum.Click += (s, e) => { printCost(10); };

            btnPomelo.Click += (s, e) => { printCost(11); };

        }



        /// <summary>

        /// 计算总共花费

        /// </summary>

        private void GetTotalCost()

        {

            //遍历 TotalCost里所有的值 全部加起来

            float tCost = 0;

            foreach (float cost in TotalCost)

            {

                tCost += cost;

            }

            lstMenu.Items.Add("------------------------");

            lstMenu.Items.Add("优惠前总价为:\t\t " + Math.Round(tCost, 1) + "元"); //打印出总价(打折前的价格)

            //调用Saving()方法 计算 总共节省的钱数 

            float totalSaving = Saving();

            lstMenu.Items.Add("打折后最终您需要付款为\t " + Math.Round((tCost - totalSaving), 1) + "元");

        }



        float tSaving = 0;

        /// <summary>

        /// 计算优惠额

        /// </summary>

        /// <returns>优惠额</returns>

        public float Saving()

        {

            for (int i = 0; i <= intQuantity.Length - 1; i++)

            {   //当物品 购买数 >= 2的时候 才有优惠  

                if (intQuantity[i] >= 2)

                {   //这里 苹果和无花果 是不存在优惠的

                    if (productList[i].Name == "苹果" || productList[i].Name == "无花果")

                        lstMenu.Items.Add("您购买了" + productList[i].Name + " 一共" + intQuantity[i] + "斤" + " 最近" + productList[i].Name + "无优惠");

                    else //否则其他水果 都有优惠

                    {

                        lstMenu.Items.Add("您购买了" + productList[i].Name + " 一共" + intQuantity[i] + "斤" + " 优惠" + Math.Round(productList[i].save(intQuantity[i]), 1) + "元");

                        tSaving += productList[i].save(intQuantity[i]);

                    }

                }

                //当购买单项 水果 小于2斤的时候 是没有优惠享受的 

                else if (1 <= intQuantity[i] && intQuantity[i] < 2)

                { 

                    lstMenu.Items.Add("您购买了" + productList[i].Name + " 只有" + intQuantity[i] + "斤" + " 没有优惠!");

                }

            }

            //最终 打印出 所有物品节约的 总价

            lstMenu.Items.Add("--------------------------------------");

            lstMenu.Items.Add("所有水果一共优惠了\t " + tSaving + "元");



            return tSaving;//返回优惠额

        }



        /// <summary>

        /// 清空购物车

        /// </summary>

        private void EmptyShoppingBox()

        {

            lstMenu.Items.Clear();  //清空listMenu控件里面的所有项(表面清除) 

            TotalCost.Clear();      //清空TotalCost里的所有项(从系统中移除)

            tSaving = 0;  //把之前节省的钱 全部清空  

            //清空的时候 要将打折省去的钱数 也清掉

            //这里用的是 清空所有购买水果的数量 当水果数为0的时候 就没有打折省去的钱数了

            for (int i = 0; i < intQuantity.Length; i++)

                intQuantity[i] = 0;

        }



        /// <summary>

        /// 删除已购买的单项物品

        /// </summary>

        private void DeleteOneShoppingItem()

        {

            //从listbox 里移除 购买项 (表面移除, 实际值需要从装载值的TotalCost集合里移除)

            lstMenu.Items.Remove(lstMenu.SelectedItem);

            //SelectedIndex 是从0开始的索引 但实际你删除项的索引是大于0的整数

            //从TotalCost里移除购买项

            TotalCost.RemoveAt(lstMenu.SelectedIndex + 1);

        }

    }

 

运行效果 如下

1.结账

C# Winform简单模拟水果店结账系统

 

2.清空购物车

C# Winform简单模拟水果店结账系统

 

3.再点结账 看下  确实所有值 都被清空了 (清空购物车功能 没问题) 

C# Winform简单模拟水果店结账系统

 

4. 但是删除单项 这里出问题了 请看下面

C# Winform简单模拟水果店结账系统

 

5 删除2项 山楂后 总价虽然正常减少了 而且原先买了3斤山楂 现在删除了2斤山楂 剩1斤

应该是没有优惠了 但这里还是保持原先 买3斤时候的优惠 

而且总优惠价格 也是不但没减少  还把之前的再次相加了一次 导致最终价格不正常 (可能还有一些问题没有发现)

C# Winform简单模拟水果店结账系统

这里思路是有 就是 根据删除项在listbox里的索引 相对应的也是在用来装载所有购买物品价格的泛型list(TotalCost)的索引

但是 怎样判断这个索引是哪个物品呢 这里是关键.

由于这里涉及到的判断比较多  个人能力有限  还请 对该程序感兴趣的大牛们 帮忙解决下

谢了!  :)

这里附上源代码 水果店结账系统 点击下载

 

你可能感兴趣的:(WinForm)