如何在VB.NET中实现厨房订单表单的自动更新显示
厨房显示系统订单自动更新问题解决方案
问题描述
我正在开发一套包含厨房显示系统的项目,已编写GetOrders()方法从数据库查询状态为'Pending'的订单,并通过WinForms控件生成可视化面板展示订单信息,但无法实现表单内容的自动更新。尝试使用Do循环时,未登录系统就出现报错;调用GetOrders().Refresh也无效果,希望得到解决该问题的方法。
现有代码
Public Sub GetOrders() Try kitchenFlowLayoutPanel.Controls.Clear() Dim i As Integer Dim sql As String sql = "SELECT c.cart_id, c.invoice_no, c.table_no, c.sale_time, f.item_name, c.serve_size, c.quantity FROM tbl_cart AS c INNER JOIN tbl_food AS f on f.item_id = c.items_id WHERE c.status='Pending'" conn.Open() cmd = New MySqlCommand(sql, conn) cmd.ExecuteReader() conn.Close() Dim dTable1 As New DataTable() Dim dAdaptor1 As New MySqlDataAdapter(cmd) dAdaptor1.Fill(dTable1) Dim panel1 As FlowLayoutPanel Dim panel2 As FlowLayoutPanel For i = 0 To dTable1.Rows.Count - 1 panel1 = New FlowLayoutPanel panel1.AutoSize = True panel1.Width = 260 panel1.Height = 500 panel1.FlowDirection = FlowDirection.TopDown panel1.BorderStyle = BorderStyle.FixedSingle panel1.Margin = New Padding(10, 10, 10, 10) panel2 = New FlowLayoutPanel panel2.BackColor = Color.FromArgb(50, 55, 89) panel2.AutoSize = True panel2.Width = 230 panel2.Height = 125 panel2.FlowDirection = FlowDirection.TopDown panel2.Margin = New Padding(0, 0, 0, 0) Dim label1 As New Label label1.ForeColor = Color.White label1.Margin = New Padding(10, 5, 3, 0) label1.Font = New Font(label1.Font, FontStyle.Bold) label1.AutoSize = True Dim label2 As New Label label2.ForeColor = Color.White label2.Margin = New Padding(10, 5, 3, 0) label2.AutoSize = True Dim label3 As New Label label3.ForeColor = Color.White label3.Margin = New Padding(10, 5, 3, 0) label3.AutoSize = True Dim label4 As New Label label4.ForeColor = Color.White label4.Margin = New Padding(10, 5, 3, 0) label4.AutoSize = True Dim label5 As New Label label5.ForeColor = Color.White label5.Margin = New Padding(10, 5, 3, 0) label5.AutoSize = True label1.Text = "Entry ID : " & dTable1.Rows(i)("cart_id").ToString label2.Text = "Invoice No : " & dTable1.Rows(i)("invoice_no").ToString label3.Text = "Table No : " & dTable1.Rows(i)("table_no").ToString label4.Text = "Order Time : " & dTable1.Rows(i)("sale_time").ToString label5.Text = Environment.NewLine & "ORDERED ITEM : " & Environment.NewLine & Environment.NewLine & " Item : " & dTable1.Rows(i)("item_name").ToString & Environment.NewLine & " Serve Size : " & dTable1.Rows(i)("serve_size").ToString & Environment.NewLine & " Qty: " & dTable1.Rows(i)("quantity").ToString & Environment.NewLine & Environment.NewLine panel2.Controls.Add(label1) panel2.Controls.Add(label2) panel2.Controls.Add(label3) panel2.Controls.Add(label4) panel2.Controls.Add(label5) panel1.Controls.Add(panel2) Dim btn As New Guna.UI2.WinForms.Guna2Button btn.AutoRoundedCorners = True btn.Size = New Size(100, 35) btn.FillColor = Color.FromArgb(241, 85, 126) btn.Margin = New Padding(60, 5, 3, 10) btn.Location = New Point(0, 0) btn.Text = "Complete" btn.Tag = dTable1.Rows(i)("cart_id").ToString ' store id AddHandler btn.Click, AddressOf btn_Click panel2.Controls.Add(btn) kitchenFlowLayoutPanel.Controls.Add(panel1) Next Catch ex As Exception conn.Close() MsgBox(ex.Message, vbCritical) End Try End Sub
解决方法
1. 修复数据库查询逻辑错误
现有代码中cmd.ExecuteReader()属于冗余操作,会占用数据库连接导致后续DataAdapter.Fill无法正常执行,直接删除该段代码,改用Using语句自动释放资源:
' 移除原有的conn.Open()、cmd.ExecuteReader()、conn.Close()三行 ' 替换为以下代码 Dim dTable1 As New DataTable() Using cmd As New MySqlCommand(sql, conn) Using dAdaptor1 As New MySqlDataAdapter(cmd) dAdaptor1.Fill(dTable1) End Using End Using
2. 用Timer实现定时自动刷新
WinForms中不要用Do循环阻塞UI线程,改用System.Windows.Forms.Timer控件实现定时更新:
- 在窗体设计器添加Timer控件(命名为
orderRefreshTimer) - 设置
Interval属性(例如5000,代表每5秒刷新一次) - 在窗体加载事件中启用Timer,并绑定Tick事件:
Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load orderRefreshTimer.Interval = 5000 ' 注意:请在登录成功后再启用Timer,避免未登录时触发数据库连接错误 ' orderRefreshTimer.Enabled = True End Sub Private Sub orderRefreshTimer_Tick(sender As Object, e As EventArgs) Handles orderRefreshTimer.Tick GetOrders() End Sub
3. 确保UI操作在主线程执行
如果后续采用异步查询数据库,必须通过Invoke确保控件更新在UI线程进行:
If kitchenFlowLayoutPanel.InvokeRequired Then kitchenFlowLayoutPanel.Invoke(Sub() GetOrders()) Else GetOrders() End If
4. 解决未登录报错问题
将Timer的启用逻辑放在登录成功之后,确保数据库连接conn已正确初始化,避免未登录时触发数据库连接错误。
内容的提问来源于stack exchange,提问作者Blood Rue
相关产品推荐
相关产品推荐

