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

嵌套DataList中DataList2_ItemCommand事件无法触发问题

三层嵌套DataList中DataList2_ItemCommand无法触发的问题修复

问题描述

使用3层嵌套的DataList控件,每层通过SQL查询加载数据。DataList1的ItemCommand事件可正常触发,页面加载时第一组数据显示正常,点击对应项能加载DataList2的数据;但DataList2的ItemCommand事件(CommandName为"Cladire")完全无法触发,无法加载DataList3的数据。

错误原因分析

  • 控件ID冲突:嵌套DataList中的LinkButton设置了ClientIDMode="Static",导致生成重复ID,破坏ASP.NET的事件路由机制。
  • 事件处理逻辑错误:DataList2_ItemCommand中错误地在当前Item内查找DataList2控件,导致无法正确获取数据ID。
  • 动态控件状态丢失:回发时未重新绑定DataList2,导致控件状态丢失,事件无法触发。

修复方案

1. 修正后端C#代码

protected void DataList1_ItemCommand(Object source, DataListCommandEventArgs e)
{
    if (e.CommandName == "Obiectiv")
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            int idob = Convert.ToInt32(DataList1.DataKeys[e.Item.ItemIndex].ToString());
            // 保存当前展开的IdOB到ViewState,用于回发时重新绑定
            ViewState["ExpandedIdOB"] = idob;

            DataList firstDataList = e.Item.FindControl("DataList2") as DataList;
            List<SqlParameter> prm = new List<SqlParameter>();
            prm.Add(new SqlParameter("@IdOB", idob));

            firstDataList.DataSource = GetDataTable("SELECT DISTINCT IdCL,Cladire FROM tblCladire WHERE IdOB= @IdOB;", prm);
            firstDataList.DataBind();

            HtmlControl theDivS = (HtmlControl)e.Item.FindControl("DivS");
            theDivS.Attributes["class"] = theDivS.Attributes["class"].Replace("hidden", "").Trim();
        }
    }
}

protected void DataList2_ItemCommand(Object source, DataListCommandEventArgs e)
{
    if (e.CommandName == "Cladire")
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            // 修正:直接从source获取当前DataList2实例,获取DataKey
            DataList currentDataList2 = source as DataList;
            int idcl = Convert.ToInt32(currentDataList2.DataKeys[e.Item.ItemIndex].ToString());
            
            DataList thirdDataList = e.Item.FindControl("DataList3") as DataList;
            List<SqlParameter> prm = new List<SqlParameter>
            {
                new SqlParameter("@IdCL", idcl)
            };

            thirdDataList.DataSource = GetDataTable("SELECT DISTINCT IdCA,Camera FROM tblCamera WHERE IdCL =@IdCL;", prm);
            thirdDataList.DataBind();

            HtmlControl theDivT = (HtmlControl)e.Item.FindControl("DivT");
            theDivT.Attributes["class"] = theDivT.Attributes["class"].Replace("hidden", "").Trim();
        }
    }
}

// 页面回发时重新绑定已展开的DataList2
protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack && ViewState["ExpandedIdOB"] != null)
    {
        int idob = Convert.ToInt32(ViewState["ExpandedIdOB"]);
        // 找到对应的DataList1项,重新绑定DataList2
        foreach (DataListItem item in DataList1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                int itemId = Convert.ToInt32(DataList1.DataKeys[item.ItemIndex]);
                if (itemId == idob)
                {
                    DataList firstDataList = item.FindControl("DataList2") as DataList;
                    List<SqlParameter> prm = new List<SqlParameter>();
                    prm.Add(new SqlParameter("@IdOB", idob));
                    firstDataList.DataSource = GetDataTable("SELECT DISTINCT IdCL,Cladire FROM tblCladire WHERE IdOB= @IdOB;", prm);
                    firstDataList.DataBind();

                    HtmlControl theDivS = (HtmlControl)item.FindControl("DivS");
                    theDivS.Attributes["class"] = theDivS.Attributes["class"].Replace("hidden", "").Trim();
                    break;
                }
            }
        }
    }
}

private static DataTable GetDataTable(string query, IEnumerable<SqlParameter> prms = null)
{
    string constr = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
    using (SqlConnection conn = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand())
        {
            cmd.CommandText = query;

            using (SqlDataAdapter sda = new SqlDataAdapter())
            {
                cmd.Connection = conn;
                sda.SelectCommand = cmd;

                DataTable dt = new DataTable();
                if (prms != null)
                {
                    foreach (var prm in prms)
                    {
                        cmd.Parameters.Add(prm);
                    }
                }
                sda.Fill(dt);
                return dt;
            }
        }
    }
}

2. 修正前端ASPX代码

移除ClientIDMode="Static",并修正重复的LinkButton ID:

<div id="DivP" runat="server">
    <div class="row no-gutters">
        <asp:DataList ID="DataList1" runat="server" Style="width: 100%" OnItemCommand="DataList1_ItemCommand" DataKeyField="IdOB">
            <ItemTemplate>
                <asp:TextBox ID="txtIDOB" class="hidden" runat="server" Text='<%#DataBinder.Eval(Container.DataItem,"IdOB")%>' />
                <asp:LinkButton ID="LinkButton10" runat="server" Text='<%#Eval("Obiectiv")%>' CommandName="Obiectiv" UseSubmitBehavior="false" Style="font-size: 11px;background-color:lightgreen" class="form-control form-control-sm" />

                <div id="DivS" runat="server" class="hidden">
                    <hr style="border: 1px solid #800080" />
                    <asp:DataList ID="DataList2" runat="server" Style="width: 100%" OnItemCommand="DataList2_ItemCommand" DataKeyField="IdCL">
                        <ItemTemplate>
                            <asp:TextBox ID="txtIDCL" class="hidden" runat="server" Text='<%#DataBinder.Eval(Container.DataItem,"IdCL")%>' />
                            <asp:LinkButton ID="LinkButton11" runat="server" Text='<%#Eval("Cladire")%>' CommandName="Cladire" UseSubmitBehavior="false" Style="font-size: 11px;background-color:lightsalmon" class="form-control form-control-sm" />

                            <div id="DivT" runat="server" class="hidden">
                                <hr style="border: 1px solid #800080" />
                                <asp:DataList ID="DataList3" runat="server" Style="width: 100%" OnItemCommand="DataList3_ItemCommand" DataKeyField="IdCA">
                                    <ItemTemplate>
                                        <asp:TextBox ID="txtIDCA" class="hidden" runat="server" Text='<%#DataBinder.Eval(Container.DataItem,"IdCA")%>' />
                                        <!-- 修正重复ID,改为LinkButton12 -->
                                        <asp:LinkButton ID="LinkButton12" runat="server" Text='<%#Eval("Camera")%>' CommandName="Camera" UseSubmitBehavior="false" Style="font-size: 11px;background-color:lightblue" class="form-control form-control-sm" />
                                    </ItemTemplate>
                                </asp:DataList>
                                <hr style="border: 1px solid #800080" />
                            </div>
                        </ItemTemplate>
                    </asp:DataList>
                    <hr style="border: 1px solid #800080" />
                </div>
            </ItemTemplate>
        </asp:DataList>
    </div>
</div>

关键修复点总结

  • 移除所有控件的ClientIDMode="Static",确保ASP.NET生成唯一的客户端ID,保证事件路由正常。
  • 修正DataList2_ItemCommand中的DataKey获取逻辑,直接通过事件源获取当前DataList实例。
  • 在Page_Load中处理回发,重新绑定已展开的DataList2,维持控件状态和事件绑定。

内容的提问来源于stack exchange,提问作者NMV

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 08:04:49