新增UC_Machine控件时timer1未启动的技术问题咨询
问题
C# WinForm项目中,主窗体Main加载正常,但当tbl_FF_Trigger表新增数据后,动态添加到myFlowLayoutPanel1的UC_Machine用户控件内的timer1未启动,导致dataGridView1无数据加载:
UC_Machine中timer1本应在UC_Machine_Load事件中启动- 主窗体通过
System.Timers.Timer定时获取机器信息,动态添加/移除UC_Machine
原因
动态创建UC_Machine并添加到容器时,Load事件不会自动触发——System.Timers.Timer的Elapsed事件运行在非UI线程,即便通过Invoke将控件添加到容器,控件的Load事件仅在控件首次显示且句柄创建完成时才会触发,直接添加控件可能无法触发该事件。
解决方案
方法1:手动触发Load事件
在主窗体中创建并配置UC_Machine实例后,直接调用其UC_Machine_Load方法,强制启动定时器。
方法2:将定时器启动逻辑移至构造函数
把timer1.Start()放到UC_Machine的构造函数中,确保实例创建时立即启动定时器,无需依赖Load事件。
方法3:重写OnLoad方法
在UC_Machine中重写控件生命周期的OnLoad方法,这比依赖Load事件回调更可靠。
修改后代码示例
方法1:主窗体代码调整
修改Timer_Elapsed中创建UC_Machine的逻辑:
if (!isExisting) { list[i] = new UC_Machine(); list[i].CRDName = item.CRDName; list[i].Model = item.Model; list[i].Machine = item.Machine; list[i].PartNumber = item.PartNumber; list[i].Workcell = item.Workcell; list[i].Date = item.Date; // 手动调用Load事件处理方法,启动timer1 list[i].UC_Machine_Load(list[i], EventArgs.Empty); itemFoods.Add(list[i]); itemFoodsFilter.Add(list[i]); existingMachine.Add(item.Machine); i++; }
方法2:UC_Machine构造函数修改
public UC_Machine() { InitializeComponent(); // 实例创建时直接启动定时器 timer1.Start(); }
方法3:UC_Machine重写OnLoad方法
protected override void OnLoad(EventArgs e) { base.OnLoad(e); timer1.Start(); }
额外风险提示
原代码中SQL查询使用字符串拼接存在SQL注入漏洞,建议改用参数化查询修复:
// UC_Machine中timer1_Tick方法修改为参数化查询 private void timer1_Tick(object sender, EventArgs e) { string query = "SELECT CRDName, PartNumber ,DefectName FROM [tbl_FF_Trigger] where Machine = @Machine"; using (SqlCommand cmd = new SqlCommand(query, db.Connection)) { cmd.Parameters.AddWithValue("@Machine", Machine); db.fillDataGridView(cmd, dataGridView1); } dataGridView1.BackgroundColor = Color.White; dataGridView1.RowHeadersVisible = false; dataGridView1.Update(); dataGridView1.Refresh(); }
需确保fillDataGridView方法支持接收SqlCommand参数,或在方法内部实现参数化逻辑
内容的提问来源于stack exchange,提问作者Peter Luong
相关产品推荐
相关产品推荐

