0

There are a few questions on here that are similar, but they didn't work for me.

I have a custom drop down list on a page, the page name is WebForm1. On WebForm1 I have an assembly reference to it: <%@ Register Assembly="GroupDropDownList" Namespace="GroupDropDownList" TagPrefix="cc1" %>

I then have a static method like this:

    public static void Populate_Country_DDL(System.Web.UI.Page page)
        {
            GroupDropDownList
                .GroupDropDownList ddlCountry =
 ((GroupDropDownList.GroupDropDownList)page.FindControl("ddlCountry"));

            using (DataContext db = new DataContext())
            {
                var country = db.Countries.OrderBy(x => x.Text);

                ddlCountry.DataSource = country; //Error here

On WebForm1 i'm trying to access the static method like this:

Utility.Populate_Country_DDL(this.Page);

The problem is that I'm getting an "Object reference not set to an instance of an object" error. I put a using statement in my utility class for GroupDropDownList

GroupDropDownList simply allows me to put option groups inside a drop down list.

Update: To fix the problem I modified my utility method to take a ContentPlaceHolder instead of Page class, and then in my calling method I found the ContentPlaceHolder within the current pages MasterPage like this:

Utility.Populate_Country_DDL(
                (ContentPlaceHolder)this.Master
                .FindControl("ContentPlaceHolder1"));
The Muffin Man
  • 19,585
  • 30
  • 119
  • 191

2 Answers2

2

I think the problem is that the control you are looking at the page was not found. Are you sure the name is correct?

FindControl method does not go down the controls hierarchy, so you'll have to write your own method which searches through all controls on the page.

E.g. recursive version:

    public static Control FindControlRecursively(Control parent, string id)
    {
        Control control = parent.FindControl(id);

        if (control != null)
        {
            return control;
        }
        else
        {
            foreach (Control childControl in parent.Controls)
            {
                control = FindControlRecursively(childControl, id);
                if (control != null)
                {
                    return control;
                }
            }
        }

        return null;
    }

Or version without recursion:

    public static Control DeepFindControl(Control parent, string id)
    {
        Queue<Control> queue = new Queue<Control>();

        queue.Enqueue(parent);

        while (queue.Count > 0)
        {
            Control currentParent = queue.Dequeue();

            Control control = currentParent.FindControl(id);

            if (control != null)
            {
                return control;
            }

            foreach (Control childControl in parent.Controls)
            {
                queue.Enqueue(childControl);
            }
        }

        return null;
    }
Andrew Bezzub
  • 15,744
  • 7
  • 51
  • 73
2

From MSDN:

The FindControl method can be used to access a control whose ID is not available at design time. The method searches only the page's immediate, or top-level, container; it does not recursively search for controls in naming containers contained on the page. To access controls in a subordinate naming container, call the FindControl method of that container.

You can only use FindControl() on the direct parent of the control you are looking for, otherwise it will return null.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335