c# - paginas - Iterar a través de TextBoxes en asp.net-¿por qué no funciona?
paginas web asp net ejemplos (3)
Tengo 2 métodos que traté de iterar a través de todos mis cuadros de texto en una página asp.net. El primero está funcionando, pero el segundo no está devolviendo nada. ¿Podría alguien explicarme por qué el segundo no funciona?
Esto funciona bien:
List<string> list = new List<string>();
foreach (Control c in Page.Controls)
{
foreach (Control childc in c.Controls)
{
if (childc is TextBox)
{
list.Add(((TextBox)childc).Text);
}
}
}
y el código "no funciona":
List<string> list = new List<string>();
foreach (Control control in Controls)
{
TextBox textBox = control as TextBox;
if (textBox != null)
{
list.Add(textBox.Text);
}
}
Necesitas recurse. Los controles están en una estructura de árbol: Page.Controls
no es una lista aplanada de todos los controles en la página. Tendría que hacer algo como lo siguiente para obtener todos los valores de TextBoxes:
void GetTextBoxValues(Control c, List<string> strings)
{
TextBox t = c as TextBox;
if (t != null)
strings.Add(t.Text);
foreach(Control child in c.Controls)
GetTextBoxValues(child, strings);
}
...
List<string> strings = new List<string>();
GetTextBoxValues(Page, strings);
Su primer ejemplo es hacer un nivel de recursión, por lo que obtendrá TextBoxes que tienen más de un control en el árbol de control. El segundo ejemplo solo obtiene TextBoxes de nivel superior (que probablemente tenga pocos o ninguno).
La clave aquí es que la colección de Controls
no es todo control en la página, sino que solo son los controles secundarios inmediatos del control actual (y una Page
es un tipo de Control
). Esos controles a su vez pueden tener sus propios controles de niños. Para obtener más información acerca de esto, lea sobre el Árbol de control de ASP.NET aquí y sobre NamingContainers aquí . Para obtener realmente cada TextBox en cualquier lugar de la página, necesita un método recursivo, como este:
public static IEnumerable<T> FindControls<T>(this Control control, bool recurse) where T : Control
{
List<T> found = new List<T>();
Action<Control> search = null;
search = ctrl =>
{
foreach (Control child in ctrl.Controls)
{
if (typeof(T).IsAssignableFrom(child.GetType()))
{
found.Add((T)child);
}
if (recurse)
{
search(child);
}
}
};
search(control);
return found;
}
Que se usa como un método de extensión , así:
var allTextBoxes = this.Page.FindControls<TextBox>(true);
puedes probar esta pieza de código para obtener una lista de todos los TextBoxes
public partial class _Default : System.Web.UI.Page
{
public List<TextBox> ListOfTextBoxes = new List<TextBox>();
protected void Page_Load(object sender, EventArgs e)
{
// after execution this line
FindTextBoxes(Page, ListOfTextBoxes);
//ListOfTextBoxes will be populated with all text boxes with in the page.
}
private void FindTextBoxes(Control Parent, List<TextBox> ListOfTextBoxes)
{
foreach (Control c in Parent.Controls) {
// if c is a parent control like panel
if (c.HasControls())
{
// search all control inside the panel
FindTextBoxes(c, ListOfTextBoxes);
}
else {
if (c is TextBox)
{
// if c is type of textbox then put it into the list
ListOfTextBoxes.Add(c as TextBox);
}
}
}
}
}