Accessing Controls Buried Inside Other Controls

Carla Romere
Carla Romere used Ask the Experts™
on
I have inherited a project created by someone who no longer works at my company. We are trying to make some modifications in how the application works and I have hit a snag.

I have a formview with the following structure:
<ContentPlaceHolder>
     <table>
          <tr>
               <td>
                    <asp:FormView>
                         <InsertItemTemplate>
                              <ddlSelectDistributor>
                                   <ddlDistributor>

I want to select a value in <ddlSelectDistributor> and have that populate the dropdown <ddlDistributor> to narrow down the choices the user has to scroll through to find their desired Distributor.

I have autopostback turned on for <ddlSelectDistributor>. Once they have selected a Distributor in <ddlDistributor>, I want to populate a few label fields all within the same <InsertItemTemplate>.

I've tried all the tricks I know to try but can't get the controls to see each other. I have moved the <SqlDataSource> to inside the <InsertItemTemplate> as suggested in one of my searches, but it's just not working yet.

On the <ddlSelectDistributor.OnSelectedIndexChanged> event, I have the following code currently:

    protected void ddlSelectDistributor_SelectedIndexChanged(object sender, EventArgs e)
    {
        DropDownList mySD = (DropDownList)FormView1.FindControl("ddlSelectDistributor");
        DropDownList myDist = (DropDownList)FormView1.FindControl("ddlDistributor");
        SqlDataSource sqlDist = (SqlDataSource)FormView1.FindControl("sqlDistributors");
        
        if (mySD.SelectedValue == "1144")
        {
            sqlDist.SelectCommand="SELECT CUSTOMER_NUMBER + '-' + LOCATION AS CUSTOMER_NUM, CUSTOMER_NAME + ' - ' + CASE SYS_STATE WHEN ' ' THEN SYS_PROVINCE ELSE SYS_STATE END + ' ' + SYS_POSTAL_CODE + ' - ' + SYS_ADDRESS_1 AS Location FROM VW_CUSTOMER_ADDRESSES WHERE (CUSTOMER_NUMBER = '1144') ORDER BY CUSTOMER_NUMBER, LOCATION";

            myDist.DataBind();
        }

        if (mySD.SelectedValue == "2335")
        {
            sqlDist.SelectCommand="SELECT CUSTOMER_NUMBER + '-' + LOCATION AS CUSTOMER_NUM, CUSTOMER_NAME + ' - ' + CASE SYS_STATE WHEN ' ' THEN SYS_PROVINCE ELSE SYS_STATE END + ' ' + SYS_POSTAL_CODE + ' - ' + SYS_ADDRESS_1 AS Location FROM VW_CUSTOMER_ADDRESSES WHERE (CUSTOMER_NUMBER = '2335') ORDER BY CUSTOMER_NUMBER, LOCATION";

            myDist.DataBind();
        }
        
    }

Open in new window


Then on the <ddlDistributor_SelectedIndexChanged> event, there is the following code:

   protected void ddlDistributor_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (((DropDownList)FormView1.Row.FindControl("ddlDistributor")).SelectedIndex == 0)
        {
            return;
        }
        string storeNbr = ((DropDownList)FormView1.Row.FindControl("ddlDistributor")).Text;
        if (storeNbr.Length > 0)
        {
            sqlSelectedDistributor.SelectParameters["CUSTOMER_NUMBER"].DefaultValue = storeNbr;
            DataView dv = (DataView)sqlSelectedDistributor.Select(DataSourceSelectArguments.Empty);
            if (dv.Table.Rows.Count == 1)
            {
                ((TextBox)FormView1.Row.FindControl("DistributorTextBox")).Text = Util.BlankForNull(dv.Table.Rows[0].ItemArray[0]);
                ((Label)FormView1.Row.FindControl("lblAddress")).Text = Util.BlankForNull(dv.Table.Rows[0].ItemArray[1]);
                ((Label)FormView1.Row.FindControl("lblStoreCSZ")).Text = Util.BlankForNull(dv.Table.Rows[0].ItemArray[2]);
                ((Label)FormView1.Row.FindControl("lblStorePhone")).Text = Util.BlankForNull(dv.Table.Rows[0].ItemArray[3]);
                ((Label)FormView1.Row.FindControl("lblStoreFax")).Text = Util.BlankForNull(dv.Table.Rows[0].ItemArray[4]);
            }
        }
        ((DropDownList)FormView1.Row.FindControl("ddlRAIssuedBy")).Focus();
    }

Open in new window


Any suggestions would be greatly appreciated.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
The problem is that control are nested under their parents, and FindControl only works at the level you point it at, not the children. In pretty much every web project I have you'll find this utility function:

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

            foreach (Control ChildControl in rootControl.Controls)
            {
                Control FoundControl = FindControlRecursive(ChildControl, controlId);

                if (FoundControl != null)
                    return FoundControl;
            }

            return null;
        }

Open in new window


so for instance

DropDownList mySD = (DropDownList)FormView1.FindControl("ddlSelectDistributor");

Open in new window


would become

DropDownList mySD = (DropDownList)FindControlRecursive(FormView1, "ddlSelectDistributor");

Open in new window

Carla RomereDirector of Information Technology

Author

Commented:
That may be the most useful information regarding buried controls that I've seen. I will be using that little code snippet from here on out!! Thank you!!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial