1、点餐系统通常由五部分组成
①第一部分:菜的编号+菜的名称+菜的单价
②第二部分:菜的编号(对应菜的编号、菜名及其价钱),其中,这个编号是可以点击的。所以它是由按钮组成的
③第三部分:是已点菜品,就是当你点击按钮时,对应的菜名就会出现在其中
④第四部分:就是消费金额,当点击菜编号按钮时,菜的价钱就直接在消费金额中直接显示和值(自动相加)
由此可知,第三和第四部分都是随第二部分的变化而变化(当用户点击菜的编号时,已点菜品和消费金额会马上改变)
2、那如何实现这些布局呢?
1、在vs2019中微软提供了一种控件,叫做FlowlayoutPanel控件
2、FlowlayoutPanel 控件是处理其组件的布局,并在流布局中自动排列,那么意思就是说,它有一个被动属性,可以自动进行排列,实则它是一个容器
3、然后,这前三个部分就可以用它来实现
①第一部分:我们要用它做一个大的容器就是父容器,并且我们还要在大的容器里边再放数个(就是你的菜的个数)这样的控件,他们叫子容器或子控件。然后我们还要用三个label放到子容器中来用作,菜的编号、菜名以菜的价钱。并且我们呢要用Tag这个属性给编号、菜名以及价钱打一个标签。标签分是“index”、“name”和“money”。
②、第二部分也是需要FlowlayoutPanel这样的控件作为父容器,子控件可以用按钮来实现,但是今天我们部用老旧的办法逐个添加,因为那样反而变的繁琐,
所以,今天第二部分是一个难点。
③、第三部分也要用FlowlayoutPanel来做父容器,子控件用label控件来实现,但是我们也不逐个添加,
所以,今天第三部分也是一个难点·
④、第四部分就是菜的价钱总和,我们直接用两个label,第一个label写文本,第二个label来显示总价钱
在这里我们用到Foreach循环遍历。那么它的格式是什么?
foreach循环只能遍历数组和集合
foreach(数据类型 数据名称 in 遍历数组(集合)){
循环体/语句;
}
分析:
既然用到Foreach循环,那么我们肯定要在它循环的时候创建按钮,创建的按钮个数=你子容器的个数,然后,按钮的文本为菜的编号,并且将子容器/控件的数据存储到创建的按钮中,并且将一次性创建的多个按钮发送到第二部分。我们可以这样干
foreach (Control item in flowLayoutPanel1.Controls)//意思就是遍历flowLayoutPanel1中控件的集合(包括控件)就是flowLayoutPanel中的子控件就是flowLayoutPanel
//Control表示数据类型为控件类型 数据类型的名称为item flowLayoutPanel1.Controls表示遍历flowLayoutPanel1控件中的控件集合
{
Button but = new Button();//实例化按钮(多个)名字叫but
but.Tag = item;//将flowLayoutPanel1控件中的子控件全部打包赋值给but的Tag属性
//注意:任何控件的属性都具有存储数据的功能
but.Size = new Size(30, 20);//设置按钮的宽高
but.Font = new Font("楷体", 10f);//设置按钮的字体和字体大小
foreach (Control type in item.Controls)//意思是遍历item(就是flowLayoutPanel子控件)中的控件集合,指的是flowLayoutPanel中的lablel
{
if (type.Tag.ToString()=="index")//判断,如果type遍历到包含控件数据的对象叫index(这个index实际上就是序号)
//因为Tag是object数据类型,而index是字符串类型,所以必须进行隐式转换
{
but.Text = type.Text;//判断结果成立,就将序号的文本赋值给but(就是按钮)
}
}
flowLayoutPanel7.Controls.Add(but);//意思是将创建的多个按钮对象以及按钮中的文本(序号)添加到flowLayoutPanel17控件中
1、现在按钮有了,按钮的编号也有了,但是点击按钮不会触发事件,所以此刻我们就要帮点按钮的事件。它是在将按钮发送给到第二部分后执行的
but.Click += But_Click;//意思是添加这些按钮的点击事件,公共的按钮绑定事件
//因为每一个按钮都对应一个菜品,所以当我们点击它的时候都会触发事件
2、那现在事件我们绑定了,所以在事件中就是执行将菜的名称和价钱发送到第三部分和第四部分。
那么该如何做呢?
第一步:要将按钮的触发对象赋值个一个定义好的变量中
//sender参数表示事件的发起者 , 也可以说sender是事件源,表示触发事件的那个组件。那么什么是事件的发起者?
//例如:我运行程序后,我没有点击,那么sender就不会触发,但是,当我按下其中一个按钮时,这个sender就触发了。
//那么就是哪个对象触发了sender那么就执行谁,或者说sender就是谁
Button clickbt = (Button)sender;//把按钮对象保存到一个类型为Button的变量中来,起名叫clickbt
//因为button是button类型,而sender是object类型,所以要将sender强制转换为Button类型
第二部:就是要将菜名发送到第三个容器中,既然是菜名,不能按,所以,是肯定要创建label,是公共的label。
然后,我们要将but.Tag 中的数据赋值给一个定义好的控件类型当中,然后我们进行Foreach循环遍历,以及if判 断,将这个定义好的控件类型中的数据(就是子容器中的控件)拿出来,分别给第三部分和第四部分。第三部分肯定就是给创建的公共label,然后发送给第三个容器中。第四个也一样的道理
Label lab = new Label();//创建label控件
Control menu =(Control) clickbt.Tag;//定义一个控件类型的变量叫menu,它获取到按钮中编号的对应子控件(就是flowLayoutPanel中的子控件就是编号+菜名+价钱)
//因为but.Tag = item;获取到flowLayoutPanel1的子控件,所以,此时tag就变为控件类型control
foreach (Control item1 in menu.Controls)
//表示遍历menu控件中的控件集合,取名叫itmer2
{
if (item1.Tag.ToString()=="name")//判断item2(就是menu控件类型,再往上说父控件中的子控件)中谁的对象名称叫name
//因为Tag是object类型,而name是string类型,所以,要通过隐式转换为string类型
{
lab.Text = item1.Text;//判断结果成立,就将item2(菜名)文本赋值给label
}
flowLayoutPanel8.Controls.Add(lab);//将label控件发送到第三个父容器当中来
}
第三部:
就是,将菜的价格遍历和判断拿出来
遍历判断的话,肯定就在上边哪个Foreach循环遍历当中。然后既然是要想计算价钱,那肯定它原本的值是0,所以就要先在全局变量中定义一个int类型爱存储这个0数据,当遍历判断结果为真,直接进行运算求和
int count = 0;//在全局变量中定义一个记录总价格的变量
if (item1.Tag.ToString()=="money")//判断item2(就是menu控件类型,再往上说父控件中的子控件)中谁的对象名称叫money
{
count += int.Parse(item1.Text);//将价钱中的字符串转换为数字用来做运算,算出总共的价钱,前提是字符串里只有数字,没有其他一些字符
//Parse();这个方法表示 将数字的字符串表示形式转换为它都等效32位有符号整数
}
}
label20.Text = count + "元";