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

UpdatePanel内Repeater按钮仅触发一次回发后消失问题求助

问题诊断与解决方案

核心问题分析

出现这个问题的核心原因集中在三点:

  1. UpdatePanel触发器覆盖不全:当前仅绑定了LIST1的触发器,LIST2的按钮回发未被纳入异步回发范围,导致第二次回发时控件状态丢失。
  2. 手动回发逻辑错误:直接调用__doPostBack触发UpdatePanel回发,未关联有效服务器端事件,后台无法正确识别操作指令,导致数据源丢失。
  3. 数据源未持久化:后台添加新行后,未将更新后的数据源存入ViewState/Session,第二次回发时数据源重置为空,parentRepeater无数据绑定导致div消失。

分步解决方案

1. 修正UpdatePanel触发器配置

给UpdatePanel添加LIST2的异步回发触发器,确保LIST2的操作被纳入异步回发范围:

<asp:UpdatePanel runat="server" ID="updPanelTeste" UpdateMode="Conditional">
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="rptProjetos" EventName="ItemCommand" />
        <!-- 添加parentRepeater的ItemCommand触发器 -->
        <asp:AsyncPostBackTrigger ControlID="parentRepeater" EventName="ItemCommand" />
    </Triggers>
    <ContentTemplate>
        <!-- 原有内容 -->
        <asp:Repeater runat="server" ID="parentRepeater" OnItemCommand="parentRepeater_ItemCommand">
            <!-- 原有ItemTemplate内容 -->
        </asp:Repeater>
    </ContentTemplate>
</asp:UpdatePanel>

2. 改用服务器端事件绑定替代手动JS回发

放弃手动__doPostBack,直接让LIST2按钮触发服务器端事件,保证状态正确传递:

<asp:Button runat="server" CssClass="buttonAcoes" Text="+" ID="btnAddLiderado"
    CommandName="AddRow"
    CommandArgument='<%# string.Format("{0}|{1}", Eval("IdProjeto"), Eval("IdAssociado")) %>'
    UseSubmitBehavior="false" />

后台parentRepeater_ItemCommand事件处理添加逻辑:

protected void parentRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    if (e.CommandName == "AddRow")
    {
        // 解析参数
        string[] args = e.CommandArgument.ToString().Split('|');
        int idProjeto = int.Parse(args[0]);
        int idAssociado = int.Parse(args[1]);

        // 从ViewState获取当前数据源
        List<YourModel> dataList = ViewState["ParentRepeaterData"] as List<YourModel> ?? new List<YourModel>();

        // 构造新行数据(根据业务逻辑赋值)
        YourModel newItem = new YourModel()
        {
            IdProjeto = idProjeto,
            IdAssociado = idAssociado,
            MarginLeftText = "",
            LeftBorder = "",
            LeftBorderLast = ""
        };
        dataList.Add(newItem);

        // 持久化数据源并重新绑定
        ViewState["ParentRepeaterData"] = dataList;
        parentRepeater.DataSource = dataList;
        parentRepeater.DataBind();

        // 手动更新UpdatePanel
        updPanelTeste.Update();
    }
}

3. 确保LIST1点击后数据源存入ViewState

在btnGerenciarProjeto_Click方法中,绑定parentRepeater时将数据源存入ViewState:

protected void btnGerenciarProjeto_Click(object sender, EventArgs e)
{
    Button btn = sender as Button;
    int idProjeto = int.Parse(btn.CommandArgument);

    // 获取初始数据(业务逻辑实现)
    List<YourModel> initialData = GetProjetoAssociados(idProjeto);

    // 持久化数据源并绑定
    ViewState["ParentRepeaterData"] = initialData;
    parentRepeater.DataSource = initialData;
    parentRepeater.DataBind();

    updPanelTeste.Update();
}

4. 若坚持原有JS逻辑的修正方案

如果必须保留原JS回发方式,需修正回发目标为有效控件事件:

function test(IdProjeto, IdAssociado) {
    const txtLider = document.getElementById('<%=txtLiderDummy.ClientID%>');
    const txtDummy = document.getElementById('<%=txtDummy.ClientID%>');
    
    txtLider.value = IdAssociado;
    txtDummy.value = IdProjeto;
    
    // 触发txtDummy的TextChanged事件而非直接回发UpdatePanel
    __doPostBack(txtDummy.uniqueID, '');
}

后台在txtDummy_TextChanged事件中执行添加逻辑,同时保证数据源存入ViewState并重新绑定parentRepeater。

关键注意事项

  • 必须将parentRepeater的数据源持久化到ViewState/Session,否则回发会重置数据。
  • UpdatePanel设为Conditional时,需手动调用updPanelTeste.Update()触发更新。
  • 尽量统一使用服务器端事件绑定,避免混合手动回发导致的状态丢失问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 06:32:08