简体   繁体   中英

Timer, UpdatePanel and dynamically created buttons

I have an update panel with a div (with runat="server") so I dynamically create and add buttons to it on a timer tick event.

The problem is that when a button is click, the is a postback but the button is gone and the event is not raised.

Here's my aspx page and my c# code behind. Nothing I write in the btn1_click actually occurs.

There's a continue to my question but in order to keep it simple, I would like to understand the above first.

I really need your help and i appreciate it, ty.

<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <asp:Timer ID="Timer1" runat="server" Interval="2000" ontick="Timer1_Tick">
    </asp:Timer>
    <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
        </Triggers>
        <ContentTemplate>
            <div id="div1" runat="server"></div>
        </ContentTemplate>
    </asp:UpdatePanel>
    <div id="div2" runat="server">div2</div>
    </form>
</body>

and this c# here.

 public partial class WebForm1 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
            }

            protected void Timer1_Tick(object sender, EventArgs e)
            {
                CreateControl();
            }

            void CreateControl()
            {
                Button btn1 = new Button();
                btn1.ID = "btn1";
                btn1.Text = "click me";
                btn1.Click += new EventHandler(btn1_Click);
                div1.Controls.Add(btn1);
            }

            void btn1_Click(object sender, EventArgs e)
            {
                div1.InnerHtml += "btn1 was clicked";
            }



        }

For dynamically added controls you must add them in every page load event. Otherwise by the time it gets to the click event the are already gone. In this case I would add the button to a session collection of buttons every time you create one, then reload that entire collection on every postback, so it doesn't lose what you've already added. Also, save an int in session that you increment so they dont all have the same ID. IDs should be unique

something like:

 protected void Page_Load(object sender, EventArgs e)
        {
          if(Page.IsPostBack)
           {
             CreateControls(YourCollectionInSession)
           }
        }
 protected void Timer1_Tick(object sender, EventArgs e)
        {
            CreateControl();
        }
 void CreateControl()
        {
            Button btn1 = new Button();
            btn1.ID = "btn" + yourSessionID;
            btn1.Text = "click me";
            btn1.Click += new EventHandler(btn1_Click);
            div1.Controls.Add(btn1);
            yourSessionID++;
            YourCollectionInSession.Add(btn1);
        }
 void CreateControl(List<Button> buttons)
        {
            foreach(Button btn in buttons)
            {
            div1.Controls.Add(btn); 
            }
        }

I've had to do the same thing before and this approach worked for me. Just remember the ASPx Page Lifecycle . It will always hit the page_init and page_load before it handles any post back events, meaning your controls are long gone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM