做一个项目是遇到的问题与求解!

8.20-8.21 完成客户资料和套餐资料相关模块。

难点:在界面的左侧显示标签页。并且在增加套餐这个环节,会涉及到在主界面显示的新增套餐的问题(如何实时更新主界面的套餐表?)。

遇到的问题:在操作中发现,在左侧显示标签页,其实很简单,tabcontrol控件中有一个属性就是设置在何处显示标签的(其中包括topleftrightbottom),这个属性是alignment

1.                  但也遇到了另一个问题:发现标签页不显示文本! (958 不过如果appearance属性为buttonflatbutton时则可显示文本,但也存在一定的问题。

2.                  在增加客户这个处理时,如何验证是否输入了足够多的信息(用户名、电话、地址)? 1136 可以简单地判断该字段是否为空。

3.                  在增加客户时,如何确定该客户的ID,可以是在原有ID的基础上增加1,那么如何获取最后一个客户的ID。而且当有客户被删除时,该ID就会空缺,如何进行填补? 1229 设置ID的为自动编号。

4.                  如何使得在添加了客户后,在客户资料汇总这个标签页下的信息能够实时地显示? 1630

这个问题是因为DataGridView与数据库绑定后,在程序运行过程中,无法知道数据库中的数据是否发生变化。从而不能实时更新。可以考虑用一个时间函数刷新(重新定义数据源):this.dataGridView1.DataSource = …..
遇到一个比较麻烦的事是我不知道为什么给DataSource重新赋值后,其中三列始终不显示数据。如果一开始就不要绑定,而是通过赋值给DataSource的话,那么DataGridView中表头显示的是数据库中的字段名。
我的选择是,索性不要绑定,在程序运行时,如果需要显示这些数据,才去从数据库中取出这些数据,将它们放入DataGridView。当有资料得到更新后,调用RefreshData()函数,重新从数据库中取出这些数据,现在在DataGridView中。首先设置好DataGridView表头要显示的每列的标题。然后把从数据库中取出的listCustomer逐项对应放入DataGridView

public void RefreshMenuData()

        {

            this.dataGridView2.Rows.Clear();

            int id;

            string dishName;

            decimal price;

            List<Dish> listDish = menuDAO.getAllDishes();

            for (int i = 0; i < listDish.Count; i++)

            {

                id = listDish[i].Id;

                dishName = listDish[i].Name;

                price = listDish[i].Price;

                this.dataGridView2.Rows.Add();

                this.dataGridView2.Rows[i].Cells[0].Value = id;

                this.dataGridView2.Rows[i].Cells[1].Value = dishName;

                this.dataGridView2.Rows[i].Cells[2].Value = price;

            }

        }

5.                  如何使得双击一行客户信息,弹出一个该客户信息的窗口,可以进行修改和删除操作。或者是增加右键功能,在右键中有删除选项? 1727 此处选择添加右键菜单(其中包括删除和修改),同时如果双击则显示修改的对话框。

6.                  在右键删除中,如何确定右键所选的用户? 1749 if (e.RowIndex >= 0 && e.ColumnIndex >= 0 && e.Button == MouseButtons.Right)
{
dgvBookmarks.Rows[e.RowIndex].Selected = true;
Rectangle r = dgvBookmarks.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);

contextMenu.Show((Control)sender, r.Left + e.X, r.Top + e.Y); 
将上面的代码加入CellMouseDown事件.  
这个问题仍旧没有解决,上面的代码只是高亮显示了所选的行,但是焦点并没有在这一行上。(1800

7.                  在客户资料中的右键时有一个Bug 1746 原来是在显示右键菜单时,此事件同时关联两个函数dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)和dataGridView2_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)。而这两个函数应该是分别响应客户和套餐信息的右键事件才对;而且,由于客户信息和套餐信息的ColumnIndex不一样(客户的多),所以导致,但右键点击客户信息时,如果其ColumnIndex值超过套餐信息的ColumnIndex值,就会报告异常。 此处,改为把两个函数合并为一个dataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)函数,在函数内部判断sender对象的发出者:DataGridView dataSender = (DataGridView)sender; if (dataSender.Name == "dataGridView1"){} else if(dataSender.Name == "dataGridView2"){}

8.                  如何实现右键按钮减少一份? (8-28 13:22)

8.22-8.24 完成订餐模块,这是整个系统的主界面和最重要的模块。

难点:如何动态显示菜单(以按钮的形式)?如何把下拉框加到ListView中,使得可以让用户修改订餐的份数?如何做到多次点击相同的菜单,使得只显示一个套餐项,而只是更改其订餐的份数?另外,需要在每个套餐的后面加个“删除”按钮。如何自动接入打进来的电话?如果是新用户,在输入了相关资料后提交,如何将这些数据写入数据库。

1.         如何自动根据数据库生成按钮。(1500 Form1_Load函数中添加如下代码:

List<Dish> listDish = menuDAO.getAllDishes();

            // 得到数据库中所有的套餐信息

            int numberOfColumn = this.tableLayoutPanel1.ColumnCount; 

            // 一行显示的按钮数

            this.tableLayoutPanel1.RowCount = (listDish.Count + 1) / numberOfColumn;  

            // 根据数据库中的套餐数,设定显示的行数

            // 动态生成按钮

            for (int tempX = 0; tempX < listDish.Count; tempX++)

            {

                int tempY = tempX / numberOfColumn;

                int column = tempX % numberOfColumn;

                int row = tempY;

                Button btn = new Button();

                this.tableLayoutPanel1.Controls.Add(btn, column, row);

               btn.Location = new Point(3 + tempX * 75, 3 + tempY * 75);

                btn.Size = new Size(75, 50);

                btn.Text = listDish[tempX].Name;

                btn.UseVisualStyleBackColor = true;

                btn.Click += new EventHandler(btn_Click);

                // 按钮关联事件

       }

2. 在点击菜单按钮之后,会在右侧的ListView中显示相应的菜单,问题是如何显示关于份数的下拉框?
        private void listView1_MouseUp(object sender, MouseEventArgs e)

        {

            // 取得列中被按下的项目

            lvItem = this.listView1.GetItemAt(e.X, e.Y);

            if (lvItem != null)

            {

                // 取得被按下之项目的周框。

                Rectangle ClickedItem = lvItem.Bounds;

                ClickedItem.X += this.listView1.Left +

                    this.listView1.Columns[0].Width +

                    this.listView1.Columns[1].Width +

                    this.listView1.Columns[2].Width;

                ClickedItem.Y += this.listView1.Top;

                // 确定comboBox的位置

                this.comboBox4.Bounds = ClickedItem;

                this.comboBox4.Width = this.listView1.Columns[3].Width;

                this.comboBox4.Text = lvItem.SubItems[3].Text;

// 使comboBox可见,并获得焦点

                this.comboBox4.Visible = true;

                this.comboBox4.BringToFront();

                this.comboBox4.Focus();

            }

        }

        private void comboBox4_KeyPress(object sender, KeyPressEventArgs e)

        {

            // 确认使用者按下 ESC 键。

            if (e.KeyChar == (char)(Keys.Escape))

            {

                // 重设原始文字值并将 comboBox 隐藏起来。

                this.comboBox4.Text = lvItem.SubItems[3].Text;

                this.comboBox4.Visible = false;

            }

            // 确认使用者按下 ENTER 键。

            else if (e.KeyChar == (char)(Keys.Enter))

            {

                // 将 ComboBox 隐藏起来。

                this.comboBox4.Visible = false;

            }

        }

        private void comboBox4_Leave(object sender, EventArgs e)

        {

            // 设定 ListView 项目的文字使其符合comboBox

            lvItem.SubItems[3].Text = this.comboBox4.Text;

            textBox12.Text = getTotalPrice().ToString();

            // 将comboBox隐藏起来

            this.comboBox4.Visible = false;

        }

        private void comboBox4_SelectedValueChanged(object sender, EventArgs e)

        {

            // 设定 ListView 项目的文字使其符合comboBox

            lvItem.SubItems[3].Text = this.comboBox4.Text;

            textBox12.Text = getTotalPrice().ToString();

            // 将comboBox隐藏起来

            this.comboBox4.Visible = false;

        }

3. 怎样求和?怎样求listView控件中订单的总价? (16:44)
private decimal getTotalPrice()

        {

            decimal totalPrice = 0;

            for (int i = 0; i < listView1.Items.Count; i++)

            {

                totalPrice += Decimal.Parse(listView1.Items[i].SubItems[tempPrice].Text) *

                    Decimal.Parse(listView1.Items[i].SubItems[tempAmount].Text);

            }

            return totalPrice;

        }

4. 今天一整天都被这个问题缠着:在其他表中都可以插入,可是在order表中却不能执行insert语句,总是提示说语法错误。(8-24)   后来,还是晓鸣发现那个表名(order)居然是关键字,真是搞死我了!

8.27-8.28完成销售统计这个模块。

难点:如何确定订单的日期,从而来统计每天的销售分数,如何自定义设定时间,并从中读取设定的时间范围?

1.       如何确定本周的第一天是哪一天?  

2.       如何显示统计时间范围内的各种套餐,即怎样加到listView中。

3.       在向orderContent表中插入数据时,由于以为orderContentID(主键)是自动编号的,不会重复,故没有指定值。可事实上,如果不指定值,不能插入同样的订单。   解决方法:指定orderContentID的值

4.       如何指定orderContentID的值? 如何获取表中最后一项的ID

5.       在显示本周、本月的订单的时候,只能显示最后一个订单号的内容。 1200 原来在根据订单号获得订单内容的时候,每次都会重新new List<Tongji>();从而导致前面取出来的订单内容在被放入listTongji之后又被清空了,只剩下最后一次的内容。解决的方法是把List<Tongji> listTongji = new List<Tongji>();放在了循环的外面。

6.       在显示统计内容的时候,如何把相同的套餐内容合并为一条记录。conn.Open();

                        OleDbCommand cmd = new OleDbCommand(strCommand, conn);

                        OleDbDataReader reader;

                        reader = cmd.ExecuteReader();

                        while (reader.Read())

                        {

                            tempTongji = new Tongji();

                            tempTongji.Amount = Int32.Parse(reader["amount"].ToString());

                            tempTongji.DishName = reader["dishName"].ToString();

                            if (listTongji.Count == 0)

                            {

                                listTongji.Add(tempTongji);

                            }

                            else

                            {

                                for (int j = 0; j < listTongji.Count; j++)

                                {

                                    if (tempTongji.DishName == listTongji[j].DishName)

                                    {

                                        listTongji[j].Amount += Int32.Parse(reader["amount"].ToString());

                                        break;

                                    }

                                    else if(j == (listTongji.Count - 1))

                                   

                                        listTongji.Add(tempTongji);

                                    }

                                }

                            }

                        }

如何使点餐中的套餐按钮和订单内容之间的位置固定不可变:this.splitContainer1.IsSplitterFixed = true;

8.       在listView中显示订单内容时,每次触发相应的事件都会从数据库中取出数据增加到listView中,而不清楚原来的数据,使得listView中的数据会有很多组。   解决方法:在向ListViewItems中添加数据之前先使用ListView.Items.Clear()清空原来的数据,然后再添加Item

9.       如何设置listView与右键菜单关联?如果在一开始的设计视图中设置ContextMenuStrip属性关联,那么即使在listview中无内容的地方鼠标右键也会出来菜单? 解决方法:对Listview的菜单,在开始的时候不要设置,而是通过下面的代码来设置:
private void listView1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        if (this.listView1.GetItemAt(e.X, e.Y) != null)
        {
            this.listView1.ContextMenuStrip = this.contextMenuStrip1;
        }
        else
        {
            this.listView1.ContextMenuStrip = null;
        }
    }
}

10.   虽然解决了第9个疑问,但是,我在显示了这个右键菜单后,如何确定到底是哪一行被选中了呢? 即我要删除这一行,该怎么办? this.listView1.FocusedItem 获取所选项!

11.   程序启动后就最大化显示:
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;

12.   在统计时,出现“未知的错误”,调式时显示:InvalidOperationException。发现数据库访问时,到一定程度后,无法继续访问!   出错原因:在统计时,由于是循环从数据库中取出相关信息,所以需要建立很多连接,可是在连接用完之后,没有及时关闭,导致连接数达到上限。在循环体最后加了语句:conn.close(); 问题解决!

13.   在统计这一块,发现每次显示都很慢,性能很差。原因分析:在执行查询操作时,由于涉及到上张表,在查询时,是每张表都建立一个查询语句。这样使得在用查询时,每个表的查询都要建立连接,并在连接用完之后将其关闭,开销极大。另外,由于如果是相同的套餐的话,还要将其amount相加更新。所以,在每次取出一个套餐时,都要遍历整个List判断这个套餐是否已经存在。   解决方法:在进行查询时,使用join,先将这些表连接起来,并且根据套餐名进行排序。这样只需要一次查询即可,而且在将套餐添加进List中时,不需要再遍历整个List,而是判断前面一项是否与新项的套餐名一致,如果一致,则更新amount,否则,在List中新增一项。

原文地址:https://www.cnblogs.com/adaiye/p/903809.html