how do you find all DropDownList instances in a page? - c#

the following one doesn't work:
foreach (Control control in Controls) {
if (control is DropDownList) {
DropDownList list = control as DropDownList;
...
}
}
PS: My class extends System.Web.UI.Page

You just need to replace Controls with Form.Controls
foreach (Control c in Form.Controls)
{
if (c is DropDownList)
{
// do something
}
}

Or you can use this extension:
public static IEnumerable<T> AllControls<T>(this Control startingPoint) where T : Control
{
bool hit = startingPoint is T;
if (hit)
{
yield return startingPoint as T;
}
foreach (var child in startingPoint.Controls.Cast<Control>())
{
foreach (var item in AllControls<T>(child))
{
yield return item;
}
}
}
Then you can use it for search of any type of System.Web.UI.Control within specific control. In case of DropDownList you can use it like:
IEnumerable<DropDownList> allDropDowns = this.pnlContainer.AllControls<DropDownList>();
this will find all drop downs within Panel control with ID="pnlContainer".

The problem is that some of the DropDownList controls may be nested in other controls.
If you page has a panel and all of your controls are in that panel the page's control array will only have that panel and all of the control will be in the Panel's control array.
The link that ajax81 linked to will work well.

Related

Find a specific control by name and modify its .Value property

I've found a few answers around that work fine with modifying .Text, .Checked values and so, but none of them worked when I tried changing the .Value property. I can't get that to work on progress bars.
Last I tried:
foreach (Control c in this.Controls)
{
if (c.Name == "test" && c is ProgressBar)
{
((ProgressBar)c).Value = 23;
}
}
Am I missing a using statement or something?
Assuming that your progressbar control is named "test" (all lowercase letters) and is placed directly on the surface of your form (not inside a groupbox,panel or other control container) then this code should work and simplify your work
foreach (var c in this.Controls.OfType<ProgressBar>().Where(x => x.Name == "test")
{
c.Value = 23;
}
instead if the ProgressBar is placed inside a control container (like a panel) the above code should be changed to loop over the controls collection of the container
foreach (var c in this.panel1.Controls.OfType<ProgressBar>().Where(x => x.Name == "test")
{
c.Value = 23;
}
As pointed out in the comment by KingKing, if you are absolutely sure that a control named "test" exists in your groupbox then a simple lookup in the controls collection should result in your progressbar. Looping is not necessary in this case
ProgressBar pb = this.groupBox1.Controls["test"] as ProgressBar;
if(pb != null) pb.Value = 23;
The trick here is that Controls is not a List<> or IEnumerable but a ControlCollection.
I recommend using an extension of Control. Add this class to your project:
public static class ControlExtensionMethods
{
public static IEnumerable<Control> All(this System.Windows.Forms.Control.ControlCollection controls)
{
foreach (Control control in controls)
{
foreach (Control grandChild in control.Controls.All())
yield return grandChild;
yield return control;
}
}
}
Then you can do :
foreach(var textbox in this.Controls.All())
{
// Apply logic to a control
}
Source: Click

How can I chang the text of all controls on form from another form

I have two form (Form1,form2)
this code on form2 ...
I make a loop of all controls on form1 and get name of the control (ControlName)
I want send any text (ex."sherif") to this control (case button)
foreach (Control ctrl in form1.Controls)
{
form1.Controls[ControlName]).Text = "sherif";
}
error message appears
NullReferenceException
Object reference not set to an instance of an object.
if the pointer stop above [ControlName] read name of control, but when continue
Comes an Null value
If you just want to change the Text properties of all controls in a form, this should do it:
foreach (Control ctrl in form1.Controls)
{
ctrl.Text = "sherif";
}
Note this will only change the controls in the top level and not nested controls....
If you need this for nested controls too, do it recursively:
public void RecursiveChange(Control control)
{
foreach (Control ctrl in control.Controls)
{
RecursiveChange(ctrl);
ctrl.Text = "sherif";
}
}
This method recursively returns all controls of form:
public IEnumerable<Control> GetChildControls(Control parent)
{
foreach(Control ctrl in parent.Controls)
{
yield return ctrl;
if (ctrl.HasChildren)
yield return GetChildControls(ctrl);
}
}
Updating text:
foreach(var ctrl in GetChildControls(form1))
ctrl.Text = "sherif";
You have to loop all controls. Some of them can be inside panels.
Use this recursive method:
private void SetText(Control control, string text)
{
foreach (Control ctrl in control.Controls)
{
ctrl.Text = text;
SetText(ctrl, text);
}
}
Usage:
SetText(form1, "sherif");
Try this
foreach (Control c in form1.Controls)
{
if (c!= null)
{
c.text="Sherif";
}
}

How to Find All the Controls in a Form, During the Run Time

Finding all the controls in a form by Using "Reflection"
During the Run Time..
You can recursively iterate through Controls collection on a form or another control.
But you can't get all controls at runtime with reflection if they were added to a controls collection during the program run
List<Control> list = new List<Control>();
GetAllControl(this, list);
private void GetAllControl(Control c , List<Control> list)
{
foreach (Control control in c.Controls)
{
list.Add(control);
if (control.Controls.Count > 0)
GetAllControl(control , list);
}
}
You can do something like this
var controls = from control in this.Controls select control;
or if you want any specific control.
var textboxes = from textbox in this.Controls.OfType<TextBox>()
select textbox;

Looping through controls in ASP.Net C#

I have a page, which contains a table, with a couple of rows, and in that row there are checkboxes.
Now the thing I want, is to loop trough all checkboxes to see if they are checked or not.
This is my current approach:
foreach (Control c in Page.Controls)
{
if(c is Checkbox){
}
}
Now the problem is that I receive only 2 controls, the page and the Table. So the checkboxes are in:
Table -> TableRow -> TableCell -> CheckBox
Is there a way to get ALL controls on a page, instead of having to nest into it to get out the controls?
control.Controls will return the first level child controls only. For details, check this question.
Since the controls are hierarchical, every control sees only it's child controls. You have to iterate through every control to get them all.
You can find an example on how to do it here:
http://www.atrevido.net/blog/CommentView,guid,c792adbf-ce0a-4bf9-a61c-ca1a4296d0ea.aspx
A Control can act as a parent to a collection of controls as in your case .You should Iterate through the child of the parent control you are using in you page.
refer http://msdn.microsoft.com/en-us/library/system.windows.forms.control.controls%28VS.71%29.aspx
I just did a nested foreach loop like this:
List<Control> allControls = new List<Control>();
List<string> selectedIDs = new List<string>();
foreach (Control c in this.pnlTable.Controls)
{
allControls.Add(c);
if (c.Controls.Count > 0)
{
foreach (Control childControl in c.Controls)
{
allControls.Add(childControl);
if (childControl.Controls.Count > 0)
{
foreach (Control childControl2 in childControl.Controls)
{
allControls.Add(childControl2);
if (childControl2.Controls.Count > 0)
{
foreach (Control childControl3 in childControl2.Controls)
{
allControls.Add(childControl3);
}
}
}
}
}
}
}
foreach (Control control in allControls)
{
if (control is CheckBox)
{
if (((CheckBox)(control)).Checked)
{
selectedIDs.Add(((CheckBox)(control)).ID);
}
}
}
Depending of the depth of the control I added a if and foreach..
Hope this helps someone else with the same issue...

How to get controls on page in master detail page?

I have master page and its content page. I want to get the textboxes situated on Content page. How can I get them in C# code behind of Content page?
Access it by using it's ID:
Markup:
<asp:TextBox runat="server" ID="myTextBox"></asp:TextBox>
Code behind:
myTextBox.Text = "This is a text!";
Note that you need to add runat="server" for it to be accessible.
Edit
After your comment I think I understand where you're getting at. You'll need to traverse through all controls down the control tree to find all TextBoxes.
Here is a recursive implementation:
public List<Control> FindControls(Control root, Type type)
{
var controls = new List<Control>();
foreach (Control ctrl in root.Controls)
{
if (ctrl.GetType() == type)
controls.Add(ctrl);
if (ctrl.Controls.Count > 0)
controls.AddRange(FindControls(ctrl, type));
}
return controls;
}
To get all TextBoxes in a page you'll call it with Page as root Control:
var allTextBoxes = FindControls(Page, typeof(TextBox));
The above example is to clarify the idea of how you should proceed. I'd do it a bit differently by using an Extension Method:
public static class ExtensionMethods
{
public static IEnumerable<Control> FindControls(this Control root)
{
foreach (Control ctrl in root.Controls)
{
yield return ctrl;
foreach (Control desc in ctrl.FindControls())
yield return desc;
}
}
}
Now you can use it directly on any control and even apply Linq on the result since it's an IEnumerable.
This will get you an array of all controls in a page:
var allControls = this.FindControls().ToArray();
To get an array of all TextBox controls:
var allTextBoxes = this.FindControls()
.OfType<TextBox>().ToLArray<TextBox>();
and to get a list of TextBoxes with a specific id:
var myTextBox = this.FindControls()
.OfType<TextBox>()
.Where<TextBox>(tb => tb.ID.Equals("textBox1")).ToList<TextBox>();
You can also use it in foreach statements:
foreach (Control c in this.FindControls())
{
...
}

Categories

Resources