简体   繁体   中英

How to Dynamically get All controls (and it's IDs) in an aspx Page?

HEllo, I need to dynamically activate fields in a page according to the service that is going to be executed...

Let me explain:

There's a page with all the possible fields and a ListBox with all the selected services to be executed, then when the user selects which service to execute (change a car plate, for example), then I need to activate only the field(s) that the service require... (The realationship between Services and Fields are stored in a database).

public void CheckAll(int pService_Id, Control pPage)
{

    foreach (Control control in pPage.Controls)
    {
        busExecutaServico vExecuta = new busExecutaServico();

        if (vExecuta.EnableField(control.ID.ToString(), Convert.ToInt32(listBoxServices.SelectedValue)))
        {
            switch (control.GetType().ToString())
            {
                case "TextBox":
                    TextBox controleText = (TextBox)Page.FindControl(control.ID.ToString());
                    controleText.Enabled = true;
                    break;

Note that busExecutaServico is the class which contains the method (EnableField) for checking if the selected item matches any field on the database..

I can't seem to get the control.ID.ToString() to work properly (the ID always comes as NULL)

If anyone can help me solve this, or if there's another way (even if it's completely different from what i'm trying), it would be of great help. thanks

I like to use a recursive function for locating controls by either type or ID.

public Control FindControlRecursive(Control rootControl, string controlId)
{
    if (rootControl.ID == controlId)
        return rootControl;

    foreach (Control control in rootControl.Controls)
    {
        Control foundControl = FindControlRecursive(control, controlId);
        if (foundControl != null)
        {
            return foundControl;
        }
    }

    return null;
}

public Control FindControlRecursive(Control rootControl, Type type)
{
    if (rootControl.GetType().Equals(type))
        return rootControl;

    foreach (Control control in rootControl.Controls)
    {
        Control foundControl = FindControlRecursive(control, type);
        if (foundControl != null)
        {
            return foundControl;
        }
    }

    return null;
}

You can adapt these to first return a collection of controls, then process them later. Might be easier to keep track of what's happening.

I learned this technique here: http://www.west-wind.com/Weblog/posts/5127.aspx

Be aware that FindControl only searches the current naming container so Page.FindControl will only find controls that are added directly to Page. For example, if you had a repeater control that had the controls you were looking for and it was added to Page, you could find your repeater control via Page.FindControl but it wouldn't find child controls within your repeater, you'd have to recursively perform the FindControl on all container controls in the page.

This might seem a bit strange but it allows you to have controls with the same ID existing on the same page. For example, if you had 10 instances of a user control with textboxes within them called "MyName", you'd really want them to not being over-writing each other's 'MyName' fields!

Your code will come across a null for an ID unless every control has been given an ID.

Also why use:-

TextBox controleText = (TextBox)Page.FindControl(control.ID.ToString());

at all instead of:-

TextBox controleText = (TextBox)control;

and indeed since you only want to change the Enabled property consider:-

((WebControl)control).Enabled = False;

That I suspect will eliminate many case statements.

In your code you don't need to search any control - you already have it in 'control' variable. You even don't need to cast it to TextBox, just to a WebControl, just do this:

...
if (vExecuta.EnableField(control.ID.ToString(), Convert.ToInt32(listBoxServices.SelectedValue)))
    ((WebControl)control).Enabled = true;

PS control.ID is already string, so you should remove any ID.ToString() also.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM