C# 如何订阅无实例名的动态生成UserControl的自定义事件
解决方法
你不需要提前声明控件实例名,在循环创建实例时直接绑定事件即可,触发事件时通过sender参数就能拿到对应控件的属性,具体操作如下:
1. 修改动态创建控件的逻辑,创建时直接订阅自定义事件
把原来直接在Add方法里new控件的逻辑拆分,先创建局部变量存储当前TaskSubject实例,绑定事件后再加入容器:
taskSubjectPanel.Controls.Clear(); DataTable taskdata = new DataTable(); sql.Connect("JonasW"); taskdata = sql.GetTasks(username); sql.Disconnect(); if(taskdata.Rows.Count>0) { for (int i = 0; i < taskdata.Rows.Count; i++) { // 临时变量存储当前创建的TaskSubject实例 var currentTaskCtl = new TaskSubject(taskdata.Rows[i][0].ToString(), taskdata.Rows[i][1].ToString(), taskdata.Rows[i][2].ToString(), taskdata.Rows[i][3].ToString(), taskdata.Rows[i][4].ToString(), taskdata.Rows[i][5].ToString(), taskdata.Rows[i][6].ToString()); // 直接订阅自定义事件,绑定到你写的处理方法 currentTaskCtl.TaskSubjectClick += OnTaskSubjectClick; // 再添加到容器 taskSubjectPanel.Controls.Add(currentTaskCtl); } } taskSubjectPanel.Refresh();
2. 实现事件处理方法,从sender获取点击的控件实例和对应DataTable
事件触发时sender参数就是你点击的那个TaskSubject控件,强制转换后就能访问它的公共taskdata属性:
private void OnTaskSubjectClick(object sender, EventArgs e) { // 把sender转成TaskSubject类型,拿到被点击的控件实例 var clickedTask = (TaskSubject)sender; // 直接访问该控件对应的DataTable属性 DataTable targetData = clickedTask.taskdata; // 这里写你需要的后续业务逻辑,比如展示详情、编辑数据等 }
补充说明
- 每个动态创建的控件都会绑定同一个事件处理方法,通过
sender可以完美区分是哪个控件触发的事件,不会互相混淆 - 不需要给每个控件设置唯一名称,也不需要额外存储控件实例列表,上述方法已经能覆盖需求
内容的提问来源于stack exchange,提问作者Jooonnnaass
相关产品推荐
相关产品推荐

