You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 23:36:03