views:

323

answers:

5

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

+1  A: 

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!

Neil Trodden
Well, the controls are already in the page... I have Stored in a database only it's names.. so i can check if the control.ID matches the ID stored in the database
A: 

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;

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

Kamarey
+1  A: 

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.

AnthonyWJones
+2  A: 

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

Matt Sherman
A: 

Hey Guys, thank you for all the help... I was debuging this code and I saw that with this code, the "foreach" count was returning only 1 Control. And it was the Masterpage... and it have no ID. is there a way for me to do the same loop, but passing the Masterpage as a parameter instead? or maybe other way at all? thank you again

This should really be an edit to your question. Matt's answer should give you the code you need: http://stackoverflow.com/questions/875537#875709 - the master page has a controls collection that would be called through his recursive sample.
Zhaph - Ben Duguid