2009-02-16 9 views
13

Tengo el siguiente código muy simpleAdición de controles dinámicamente a un UpdatePanel de ASP.NET AJAX

<asp:ScriptManager ID="ScriptManager1" runat="server"> 
</asp:ScriptManager> 

<asp:UpdatePanel ID="UpdatePanel1" runat="server"> 
<ContentTemplate> 
    <asp:PlaceHolder ID="PlaceHolder1" runat="server"> 
    </asp:PlaceHolder> 
    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" /> 
</ContentTemplate> 
</asp:UpdatePanel> 

Y el código subyacente

protected void Button1_Click(object sender, EventArgs e) 
{ 
    Literal literal = new Literal(); 
    literal.Text = DateTime.Now.ToString(); 
    literal.ID = DateTime.Now.Ticks.ToString(); 

    // These both work fine the first time the button is clicked 
    // but the second time nothing is added. 
    UpdatePanel1.ContentTemplateContainer.Controls.Add(literal); 
    PlaceHolder1.Controls.Add(literal); 
} 

Mi problema viene en que sólo es añadido cada vez el control literal una vez. Recorrí sitios de blogs y de google (más libros) pero sin suerte. ¿Qué me estoy perdiendo?

Respuesta

22

En asp.net, los controles en el archivo ASPX se generan automáticamente en cada devolución. Los controles que ha creado no están en el código ASPX, por lo que el marco no los crea para usted. La primera vez que ejecuta el método Button1_Click, agrega un control adicional a la página. La segunda vez que ejecutas el método Button1_Click, estás en otra publicación y ese primer botón extra se ha olvidado. Entonces, el resultado de esa devolución de datos es que obtienes un botón extra otra vez.

Esto creará un control extra cada vez que se pulsa el botón (aunque las marcas de tiempo se actualizará cada vez que se pulsa el botón, porque se vuelven a crear los controles)

protected void Button1_Click(object sender, EventArgs e) 
{ 
    int count = 0; 

    if (ViewState["ButtonCount"] != null) 
    { 
     count = (int)ViewState["ButtonCount"]; 
    } 

    count++; 
    ViewState["ButtonCount"] = count; 

    for (int i = 0; i < count; i++) 
    { 
     Literal literal = new Literal(); 
     literal.Text = DateTime.Now.ToString(); 
     literal.ID = DateTime.Now.Ticks.ToString(); 

     UpdatePanel1.ContentTemplateContainer.Controls.Add(literal); 
     PlaceHolder1.Controls.Add(literal); 
    }    
} 
+0

Exactamente lo que estaba buscando, gracias –

1

Estoy de acuerdo en la respuesta anterior Sin embargo, este enfoque no salvará el estado de los controles dinámicos (o para ser exactos, salvará el estado pero no los cargará de nuevo). El estado de la vista de carga se llama en la sección Cargar evento del ciclo de vida de la página, donde asigna los valores de control guardados en el estado de visualización. Sin embargo, si los controles no se crean en este momento, no se pueden cargar con datos anteriores, por lo que para mantener el estado, los nuevos controles deben volver a crearse en o antes del evento de carga.

protected void Page_Load(object sender, EventArgs e) 
{ 
    //PS: Below approach saves state as id is constant, it simply generates a new control with same id hence viewstate loads the value 
    if (IsPostBack) 
    { 
     int count = 0; 

     if (ViewState["ButtonCount"] != null) 
     { 
      count = (int)ViewState["ButtonCount"]; 
     } 

     count++; 
     ViewState["ButtonCount"] = count; 

     for (int i = 0; i < count; i++) 
     { 
      TextBox literal = new TextBox(); 
      //literal.Text = DateTime.Now.ToString(); 
      literal.ID = "Textbox" + i.ToString(); 

      //UpdatePanel1.ContentTemplateContainer.Controls.Add(literal); 
      PlaceHolder1.Controls.Add(literal); 

     } 
    } 
} 

Dynamically adding controls View State and postback

+1

acordado, esto es mejor. Mantener el ID de la misma forma en las devoluciones permite que viewstate se aplique correctamente. Sin embargo, esto debe hacerse en Init de la página según http://msdn.microsoft.com/en-us/library/ms972976.aspx –

Cuestiones relacionadas