2010-11-23 75 views
6

tengo que recorrer todos los controles en mi página web asp.net y hacer algo para el control. En un caso que estoy haciendo una cadena gigante de la página y enviarla por correo electrónico a mí mismo, y en otro caso estoy guardar todo en una cookie.Recorrer todos los controles en la página web asp.net

El problema es masterpages y los objetos de las colecciones de controles dentro de ellos. Quiero ser capaz de pasar de una página con el método, entonces ese método sea genérica suficiente para recorrer todos los controles en la página del centro de la mayoría de los contenidos y trabajar con ellos. Intenté hacer esto con la recursión, pero mi recursión es incompleta.

Quiero pasar un objeto de página en un método, y tienen ese método bucle a través de todos los controles en la página de contenido más profundo. ¿Cómo puedo conseguir esto?

private static String controlToString(Control control) 
{ 
    StringBuilder result = new StringBuilder(); 

    String controlID = String.Empty; 

    Type type = null; 

    foreach (Control c in control.Controls) 
    { 
     try 
     { 
      controlID = c.ID.ToString(); 

      if (c is IEditableTextControl) 
      { 
       result.Append(controlID + ": " + ((IEditableTextControl)c).Text); 
       result.Append("<br />"); 
      } 
      else if (c is ICheckBoxControl) 
      { 
       result.Append(controlID + ": " + ((ICheckBoxControl)c).Checked); 
       result.Append("<br />"); 
      } 
      else if (c is ListControl) 
      { 
       result.Append(controlID + ": " + ((ListControl)c).SelectedValue); 
       result.Append("<br />"); 
      } 
      else if (c.HasControls()) 
      { 
       result.Append(controlToString(c)); 
      } 

      //result.Append("<br />"); 
     } 
     catch (Exception e) 
     { 

     } 
    } 

    return result.ToString(); 
} 

Sin try/catch

referencia a objeto no establecida como instancia de un objeto.

En la línea ID del control = .....

+0

¿Cuál es el error que está obteniendo? –

+0

No hay error, mi cadena simplemente no tiene entradas que representen todos los controles. – MAW74656

+0

La razón por la que no está consiguiendo un error es porque tiene un bloque try/catch ocultarlo. Eliminar eso y ver qué pasa. –

Respuesta

8

Su método original no funcionará si se inicia desde el elemento raíz del documento: algo así como page.Controls ya que sólo se repetirá a través el primer nivel de controles, pero recuerda que un control puede ser compuesto. Entonces necesitas recursividad para lograr eso.

 public void FindTheControls(List<Control> foundSofar, Control parent) 
     { 

      foreach(var c in parent.Controls) 
      { 
        if(c is IControl) //Or whatever that is you checking for 
        { 

         foundSofar.Add(c); 

         if(c.Controls.Count > 0) 
         { 
          this.FindTheControls(foundSofar, c); 
         } 
        } 


      } 

     } 
+0

Ok, ¿puedo pasar un objeto de página a esto? ¿Qué puedo pasar a esto? – MAW74656

+0

Además, ¿cuál es la ventaja de usar var c sobre Control c? – MAW74656

+1

@ MAW74656 Azúcar sintáctico, son los mismos – Prescott

0
sub getcontrols(byref c as control, byref allControls as list(of control) 
if c isnot nothing 
allcontrols.add(c) 
if c.controls.count>0 then 
for each ctrl as control in c.controls 
getcontrols(ctrl,allcontrols) 
next 
end if 
+0

¿Cómo hacer esto en C#? – MAW74656

+0

No estoy seguro de que esto sea relevante para la pregunta de ASP.net. – JackAce

+0

Lenguaje incorrecto, lo siento. –

1
foreach (Control ctlMaster in Page.Controls) 
{ 
    if (ctlMaster is MasterPage) 
    { 
     foreach (Control ctlForm in ctlMaster.Controls) 
     { 
      if (ctlForm is HtmlForm) 
      { 
       foreach (Control ctlContent in ctlForm.Controls) 
       { 
        if (ctlContent is ContentPlaceHolder) 
        { 
         foreach (Control ctlChild in ctlContent.Controls) 
         { 
          //Do something! 
         } 
        } 
       } 
      } 
     } 
    } 
} 

Esto debe hacerlo. Sin embargo, es posible que deba verificarlo para asegurarse de que realmente está tratando con el ContentPlaceHolder correcto si hay más de uno.

23

bien me gusta el enfoque LINQ David Finleys a FindControl http://weblogs.asp.net/dfindley/archive/2007/06/29/linq-the-uber-findcontrol.aspx

public static class PageExtensions 
{ 
    public static IEnumerable<Control> All(this ControlCollection controls) 
    { 
     foreach (Control control in controls) 
     { 
      foreach (Control grandChild in control.Controls.All()) 
       yield return grandChild; 

      yield return control; 
     } 
    } 
} 

Uso:

// get the first empty textbox 
TextBox firstEmpty = accountDetails.Controls 
    .All() 
    .OfType<TextBox>() 
    .Where(tb => tb.Text.Trim().Length == 0) 
    .FirstOrDefault(); 

// and focus it 
if (firstEmpty != null) 
    firstEmpty.Focus(); 
+2

+1 porque ... ¡te lo mereces! – ileon

+2

Por cierto ... ¡Funciona! – ileon

+0

Esto no funciona en ASP.net 2 o VS2005 – Fandango68

0

Esto funcionó para mí ..

sólo asegúrese de identificación de todos tus mandos a partir de los prefijos que se muestran a continuación. es decir: <asp:TextBox ID="TextBoxEmail"...> por ejemplo. De lo contrario, el analizador no detectará su control. Si alguien tiene una forma mejor de analizar sin saber/codificar la ID de los controles, eso sería aún más dulce.

protected String GetControls(Control control) 
{ 
    //Get text from form elements 
    String text = ""; 
    foreach (Control ctrl in control.Controls) 
    { 
     if (ctrl.ClientID.Contains("TextBox")) 
     { 
      TextBox tb = (TextBox)ctrl; 
      text += tb.ID.Replace("TextBox", "") + ": " + tb.Text + "<br />"; 
     } 
     if (ctrl.ClientID.Contains("RadioButtonList")) 
     { 
      RadioButtonList rbl = (RadioButtonList)ctrl; 
      text += rbl.ID.Replace("RadioButtonList", "") + ": " + rbl.SelectedItem.Text + "<br />"; 
     } 
     if (ctrl.ClientID.Contains("DropDownList")) 
     { 
      DropDownList ddl = (DropDownList)ctrl; 
      text += ddl.ID.Replace("DropDownList", "") + ": " + ddl.SelectedItem.Text + "<br />"; 
     } 

     if (ctrl.ClientID.Contains("CheckBox")) 
     { 
      CheckBox cb1 = (CheckBox)ctrl; 
      text += cb1.ID.Replace("CheckBox", "") + ": " + cb1.Text + "<br />"; 
     } 

     if (ctrl.HasControls()) 
      text += GetControls(ctrl); 
    } 

    return text; 
} 

Y llamarlo, pasando objeto de página ...

String log; 
foreach (Control ctrl in Page.Controls) 
    log += GetControls(ctrl); 
0

Por favor, encontrar el código de abajo. Esto debería ayudarte con todos los controles que necesitas. Debería poder usar Controles de Página Web, así como Controles ASP.NET.

public partial class Default : System.Web.UI.Page 
{ 

List<Control> lstControl = new List<Control>(); 

protected void Page_Load(object sender, EventArgs e) 
{ 

} 

private List<Label> getLabels() // Add all Lables to a list 
{ 
    List<Label> lLabels = new List<Label>(); 

    foreach (Control oControl in Page.Controls) 
    { 
     GetAllControlsInWebPage(oControl); 
    } 

    foreach (Control oControl in lstControl) 
    { 
     if (oControl.GetType() == typeof(Label)) 
     { 
      lLabels.Add((Label)oControl); 
     } 
    } 
    return lLabels; 
} 

protected void GetAllControlsInWebPage(Control oControl) 
{ 
    foreach (Control childControl in oControl.Controls) 
    { 
     lstControl.Add(childControl); //lstControl - Global variable 
     if (childControl.HasControls()) 
      GetAllControlsInWebPage(childControl); 
    } 
} 

} 
Cuestiones relacionadas