Update Panel: inserire controlli a runtime

Ultimamente ho riaffrontato un problema che avevo già affrontato con Davide:

Inserire dei controlli a runtime in un updatepanel.

Per farvi capire il problema, provate ad eseguire il seguente codice, ogni qual volta dovete aggiornare il vostro update panel:

                TextBox newtxt = new TextBox();                             
                newtxt.ID = Guid.NewGuid().ToString();                      
                Literal l = new Literal();                                  
                l.Text = "<br />";                                          
                UpdatePanel1.ContentTemplateContainer.Controls.Add(newtxt); 
                UpdatePanel1.ContentTemplateContainer.Controls.Add(l);      

vedrete che verrà inserito un nuovo controllo TextBox all'interno dell'updatepanel.
Se proverete a rilanciare il codice, verrà creata una nuova TextBox e perderete quella vecchia.

Questo capita perchè dopo il postback i controlli inseriti a runtime non vengono ricreati. Toccherà a noi occuparci della ricreazione degli elementi utilizzando la ViewState della pagina:

Default.aspx

<body>                                                                              
    <form id="form1" runat="server">                                                
    <asp:ScriptManager ID="ScriptManager1" runat="server">                          
    </asp:ScriptManager>                                                            
    <div style="float: left">                                                       
        <asp:Label ID="lblOutUpdate" runat="server" /><br />                        
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">                          
            <ContentTemplate>                                                       
                <asp:Label ID="lblInUpdate" runat="server" /><br />                 
                <asp:TextBox ID="txtUpdatePanel0" runat="server" /><br />           
            </ContentTemplate>                                                      
            <Triggers>                                                              
                <asp:AsyncPostBackTrigger ControlID="bntOk" EventName="Click" />    
            </Triggers>                                                             
        </asp:UpdatePanel>                                                          
    </div>                                                                          
    <div style="float: right">                                                      
        <asp:Button ID="bntOk" runat="server" Text="Ok" onclick="bntOk_Click" />    
    </div>                                                                          
    </form>                                                                         
</body>                                                                             
Default.aspx.cs
    public partial class _Default : System.Web.UI.Page                                  
    {                                                                                   
        protected void Page_Load(object sender, EventArgs e)                            
        {                                                                               
            lblOutUpdate.Text = "Out updatepanel: " + DateTime.Now.ToString();          
        }                                                                               
                                                                                        
        protected void bntOk_Click(object sender, EventArgs e)                          
        {                                                                               
            lblInUpdate.Text = "In updatepanel: " + DateTime.Now.ToString();            
            txtUpdatePanel0.Enabled = false;                                            
                                                                                        
            var r = from q in Request.Form.AllKeys                                      
                    where q.StartsWith("txtUpdatePanel") && !q.Equals("txtUpdatePanel0")
                    select q;                                                           
                                                                                        
            for (int i = 0; i < r.Count(); i++)                                         
            {                                                                           
                TextBox newtxt = new TextBox();                                         
                newtxt.ID = r.ElementAt(i);                                             
                newtxt.Text = Request.Form.Get(r.ElementAt(i));                         
                newtxt.Enabled = false;                                                 
                Literal l = new Literal();                                              
                l.Text = "<br />";                                                      
                UpdatePanel1.ContentTemplateContainer.Controls.Add(newtxt);             
                UpdatePanel1.ContentTemplateContainer.Controls.Add(l);                  
            }                                                                           
                                                                                        
            TextBox txt = new TextBox();                                                
            txt.Text = "";                                                              
            txt.ID = "txtUpdatePanel" + (r.Count() + 1).ToString();                     
            UpdatePanel1.ContentTemplateContainer.Controls.Add(txt);                    
        }                                                                               
    }                                                                                   

In pratica, ogni qual volta si scatenerà l'evento associato all'update panel, andremo a recuperare tutti i controlli creati dinamicamente, li ricreeremo con i valori inseriti ed inseriremo il nuovo controlo che potrà esser utilizzato dall'utente.

Spero possa tornarvi utile.

Tags:  |