Scroll through all the controls on asp.net

I need to iterate over all the controls on my asp.net webpage and do something for the control. In one case, I make a giant line from a page and send it by e-mail to myself, and in the other case I save all cookies.

The problem is the master pages and elements with collections of controls inside them. I want to be able to pass the page to a method, then this method will be general enough to iterate over all the controls on the innermost content page and work with them. I tried to do this with recursion, but my recursion is incomplete.

I want to pass the page object to a method and pass this method through all the controls on the innermost content page. How can I achieve this?

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(); } 

Without try / catch

The reference to the object is not installed in the instance of the object.

On line controlID = .....

+6
c # webforms master-pages
source share
6 answers

Your original method will not work if you start with the root element of your document: something like page.Controls, since you will only project the first level of controls, but remember that the control can be composite. So you need recursion to take this off.

  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); } } } } 
+8
source share

I prefer David Finleys linq's approach to 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; } } } 

Using:

 // 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(); 
+23
source share
 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! } } } } } } } 

That should do it. Although you may need to do some checks to make sure that you are really dealing with the correct ContentPlaceHolder, if there are more than one.

+1
source share
 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
source share

It worked for me ..

Just make sure you specify all of your controls, starting with the prefixes shown below. i.e.: <asp:TextBox ID="TextBoxEmail"...> for example. Otherwise, the analyzer will not detect your control. If someone has a better way to parse without knowing / hard coding the identifier of the controls, this will be even sweeter.

 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; } 

And to call it, passing the page object ...

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

Please find the code below. This should help you with all the necessary controls. You should be able to use web page controls as well as ASP.NET controls.

 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); } } } 
0
source share

All Articles