Sí, esto es posible. Una forma de hacer esto usando puramente ASP.NET (que parece lo que está pidiendo) sería mantener un recuento de los controles TextBox
que ha agregado (almacenando ese valor en el ViewState
) y recrear los controles TextBox
en el Page_Load
evento. Por supuesto, hoy en día la mayoría de la gente probablemente usarían Javascript o jQuery para manejar este lado del cliente tarea, pero armar un ejemplo rápido para demostrar cómo funciona con las devoluciones de datos:
portada:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DynamicControls.aspx.cs" Inherits="MyAspnetApp.DynamicControls" EnableViewState="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"></head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnAddTextBox" runat="server" Text="Add" OnClick="btnAddTextBox_Click" />
<asp:Button ID="btnWriteValues" runat="server" Text="Write" OnClick="btnWriteValues_Click" />
<asp:PlaceHolder ID="phControls" runat="server" />
</div>
</form>
</body>
</html>
Código detrás :
using System;
using System.Web.UI.WebControls;
namespace MyAspnetApp
{
public partial class DynamicControls : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Recreate textbox controls
if(Page.IsPostBack)
{
for (var i = 0; i < TextBoxCount; i++)
AddTextBox(i);
}
}
private int TextBoxCount
{
get
{
var count = ViewState["txtBoxCount"];
return (count == null) ? 0 : (int) count;
}
set { ViewState["txtBoxCount"] = value; }
}
private void AddTextBox(int index)
{
var txt = new TextBox {ID = string.Concat("txtDynamic", index)};
txt.Style.Add("display", "block");
phControls.Controls.Add(txt);
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
AddTextBox(TextBoxCount);
TextBoxCount++;
}
protected void btnWriteValues_Click(object sender, EventArgs e)
{
foreach(var control in phControls.Controls)
{
var textBox = control as TextBox;
if (textBox == null) continue;
Response.Write(string.Concat(textBox.Text, "<br />"));
}
}
}
}
Puesto que usted está volviendo a crear los controles en cada devolución de datos, los valores introducidos en los cuadros de texto se conservará a través de cada devolución de datos. Agregué btnWriteValues_Click
para demostrar rápidamente cómo leer los valores de los cuadros de texto.
EDITAR
He actualizado el ejemplo añadir un panel que contiene un cuadro de texto y un botón Quitar. El truco aquí es que el botón Eliminar no elimina el Panel contenedor, simplemente hace que no sea Visible. Esto se hace para que todos los ID de control permanezcan iguales, por lo que los datos ingresados permanecen con cada cuadro de texto. Si tuviéramos que eliminar el TextBox por completo, los datos después del TextBox que se eliminó cambiarían un TextBox en la siguiente devolución (solo para explicar esto un poco más claro, si tenemos txt1, txt2 y txt3, y eliminamos txt2, en la siguiente devolución de datos crearemos dos cuadros de texto, txt1 y txt2, y se perderá el valor que estaba en txt3).
public partial class DynamicControls : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
for (var i = 0; i < TextBoxCount; i++)
AddTextBox(i);
}
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
AddTextBox(TextBoxCount);
TextBoxCount++;
}
protected void btnWriteValues_Click(object sender, EventArgs e)
{
foreach(var control in phControls.Controls)
{
var panel = control as Panel;
if (panel == null || !panel.Visible) continue;
foreach (var control2 in panel.Controls)
{
var textBox = control2 as TextBox;
if (textBox == null) continue;
Response.Write(string.Concat(textBox.Text, "<br />"));
}
}
}
private int TextBoxCount
{
get
{
var count = ViewState["txtBoxCount"];
return (count == null) ? 0 : (int) count;
}
set { ViewState["txtBoxCount"] = value; }
}
private void AddTextBox(int index)
{
var panel = new Panel();
panel.Controls.Add(new TextBox {ID = string.Concat("txtDynamic", index)});
var btn = new Button { Text="Remove" };
btn.Click += btnRemove_Click;
panel.Controls.Add(btn);
phControls.Controls.Add(panel);
}
private void btnRemove_Click(object sender, EventArgs e)
{
var btnRemove = sender as Button;
if (btnRemove == null) return;
btnRemove.Parent.Visible = false;
}
}
Los controles * deben * volver a crearse en la devolución de datos. Sin embargo, hay algunos proyectos para automatizar esta tarea, como [DynamicControlPlaceholder] (http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx) (persiste y luego vuelve a crear los controles). –
sí, he leído sobre esto, pero me gustaría aprender esto :) – Shaokan