【问题标题】:CheckedChanged EventHandler of dynamically added Checkboxes not firing inside UpdatePanel of a RepeaterCheckedChanged EventHandler 动态添加的复选框未在中继器的 UpdatePanel 内触发
【发布时间】:2011-03-16 10:05:26
【问题描述】:

我在这里阅读了大多数帖子,但我无法弄清楚为什么“CheckedChanged”事件没有触发。这是我的情况。

我正在使用中继器从数据库中生成项目。每个 ReapeaterItem 都应该包含一个 UpdatePanel,因为我必须更新 UpdatePanel 中的控件并且不想重新加载整个页面。在这些动态生成的 UpdatePanel 中(每个 RepeaterItem 都有一个),我动态添加了三个复选框(基于数据库)。这些复选框需要触发“CheckedChanged”事件,因为在某些情况下,我想根据业务逻辑启用/禁用/选中/取消选中 Checkbox1、2 或 3。 ......希望你到此为止。我正在添加所有控件并添加了 EventHandler。但是生成的代码不反映事件处理程序。我尝试了 OnItemDataBound, OnItemCreated, PreRender, ... Events 来添加 Eventhandler,但我无法找到带有 ID 的 CheckBox-Control。

我完全迷失了这一点,并且正在使用按钮而不是复选框。从我目前所读到的是,使用 Buttons 我可以使用 Button 中的 CommandName 和 Repeater 中的 ItemCommand-Event 来获得解决方法,但是我需要以某种方式在页面上反映“检查”。

顺便说一句,每个中继器 (8) 都位于一个 ajaxtoolkit-accordion 控件内。

这里我给你一些代码:

aspx-页面

<asp:Repeater ID="RepeaterAccordionPane2" runat="server">
     <ItemTemplate>
          HTML Stuff<%# DataBinder.Eval(Container.DataItem, "Header")%>HTML Stuff<%# DataBinder.Eval(Container.DataItem, "Beschreibung")%></td>
                <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode=Conditional>
                       <ContentTemplate>
                       </ContentTemplate>
                 </asp:UpdatePanel>
                 HTML Stuff
     </ItemTemplate>
</asp:Repeater>

这是 Page_Load 部分

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            dvAlleArtikel = new System.Data.DataView(...Database...);

            [... some other code here ...]
            RepeaterAccordionPane2.DataSource = dvAlleArtikel;
            //RepeaterAccordionPane2.ItemCreated +=new RepeaterItemEventHandler(RepeaterAccordionPane2_ItemCreated);
            //RepeaterAccordionPane2.PreRender +=new EventHandler(RepeaterAccordionPane2_PreRender);
            RepeaterAccordionPane2.DataBind();

            int nUpdatePanelIndex = 0;
            foreach (Control crInRepeater in RepeaterAccordionPane2.Controls)
            {
                if (crInRepeater.GetType() == typeof(RepeaterItem))
                {
                    foreach (Control crInRepeaterItem in crInRepeater.Controls)
                    {
                        if (crInRepeaterItem.GetType() == typeof(UpdatePanel))
                        {
                            LiteralControl litTabelleBeginn = new LiteralControl("<table width=\"100%\"  border=\"0\" cellspacing=\"0\" cellpadding=\"2\">");
                            ((UpdatePanel)crInRepeaterItem).ContentTemplateContainer.Controls.Add(litTabelleBeginn);

                            if (dvAlleArtikel[nUpdatePanelIndex]["ArtNr1"].ToString() != "0")
                            {
                                CheckBox CheckBox1 = new CheckBox();
                                CheckBox1.ID = dvAlleArtikel[nUpdatePanelIndex]["ArtNr1"].ToString();
                                CheckBox1.Text = (dvAlleArtikel[nUpdatePanelIndex]["CheckBoxLbl1"].ToString() == "" ? "leer" : dvAlleArtikel[nUpdatePanelIndex]["CheckBoxLbl1"].ToString());
                                CheckBox1.AutoPostBack = true;
                                CheckBox1.CheckedChanged +=new EventHandler(CheckBox1_CheckedChanged);

                                LiteralControl litNeueTabellenZeileBeginn = new LiteralControl("<tr><td width=10><img src=\"images/helper/spacer.gif\" width=\"10\"></td><td height=\"20\">");
                                LiteralControl litNeueTabellenZeileEnde = new LiteralControl("</td><td width=\"100\" height=\"20\">" + dvAlleArtikel[nUpdatePanelIndex]["ArtPrice1"].ToString() + " &euro; </td></tr>");

                                ((UpdatePanel)crInRepeaterItem).ContentTemplateContainer.Controls.Add(litNeueTabellenZeileBeginn);
                                ((UpdatePanel)crInRepeaterItem).ContentTemplateContainer.Controls.Add(CheckBox1);
                                ((UpdatePanel)crInRepeaterItem).ContentTemplateContainer.Controls.Add(litNeueTabellenZeileEnde);
                            }

                            [... some other code here...]

                            LiteralControl litTabelleEnde = new LiteralControl("</table>");
                            ((UpdatePanel)crInRepeaterItem).ContentTemplateContainer.Controls.Add(litTabelleEnde);
                            nUpdatePanelIndex++;
                        }
                    }
                }
            }

此代码永远无法到达:

    protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
    {
        int foo = 0;
    }

这是生成的复选框代码:

<input id="AccordionPane2_content_RepeaterAccordionPane2_ctl00_6200" type="checkbox" name="AccordionPane2_content$RepeaterAccordionPane2$ctl00$6200" onclick="javascript:setTimeout('__doPostBack(\'AccordionPane2_content$RepeaterAccordionPane2$ctl00$6200\',\'\')', 0)" />

事件已生成,但是当我单击复选框时,UpdatePanel 中的所有内容都消失了,并且不会触发 CheckedChanged-EventHandler。

我做错了什么?

感谢所有建议,我真的被困住了。

mk

【问题讨论】:

    标签: asp.net event-handling checkbox updatepanel repeater


    【解决方案1】:

    第一次加载页面时,您将所有复选框添加到 Controls 集合中,并且它们会被渲染。当您进行回发(通过 CheckBox 的 AutoPostBack)时,您有一个检查 if(!IsPostBack),它不允许将复选框添加到回发时的 Controls 集合中。因此,您将看不到控件和页面,并且当页面生命周期尝试调用事件(发生在 Page_Load 之后)时,创建事件的控件不再存在。

    您需要重构您的 Page_Load 方法,以便它做两件事 - 1,不管IsPostBack 的值如何,绑定转发器并创建动态控件。 2、如果IsPostBack==false,即初始加载,则设置动态控件的值。您不想在IsPostBack==true 时设置动态控件的值,因为那样您将丢失用户输入的值。

    另外,请注意:

    if (crInRepeater.GetType() == typeof(RepeaterItem))
    

    可以改写为:

    if (crInRepeater is RepeaterItem)
    

    【讨论】:

    • ...当页面生命周期尝试调用事件时(发生在 Page_Load 之后)...是要做的事情。我对更复杂的 asp.net 和 ajax 编程相当陌生,并且不知道页面生命周期的那一部分以及动态控件如何进行事件处理。感谢您对此的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 2020-02-01
    相关资源
    最近更新 更多