Sean Anderson
Sean Anderson

Reputation: 29331

Struggling to move away from recursive Page.FindControl

I have developed a web dashboard which has a structure of controls embedded inside of controls. In many scenarios I have the ID of a control and need to be working on the actual control object. As such, I use a utility method, a recursive FindControl implementation, which searches Page (or any other provided object, but I always use Page), for the ID of the control.

/// <summary>
/// Page.FindControl is not recursive by default.
/// </summary>
/// <param name="root"> Page </param>
/// <param name="id"> ID of control looking for. </param>
/// <returns> The control if found, else null. </returns>
public static Control FindControlRecursive(Control root, string id)
{
    if (int.Equals(root.ID, id))
    {
        return root;
    }

    foreach (Control control in root.Controls)
    {
        Control foundControl = FindControlRecursive(control, id);

        if (!object.Equals(foundControl,null))
        {
            return foundControl;
        }
    }

    return null;
}

This function has the ability to become quite slow. I realize just how slow once I put log4net logging into it. I am now trying to move away from it where I can, but I am not sure what other options I have, if any.

For instance, the user drag-and-drops a control onto my web page. The event handler looks like this:

protected void RadListBox_Dropped(object sender, RadListBoxDroppedEventArgs e)
{
    //e.HtmlElementID is the UniqueID of the control I want to work upon.
    RadDockZone activeControlDockZone = Utilities.FindControlRecursive(Page, e.HtmlElementID) as RadDockZone;
}

There is no guarantee that this control will be the direct child of Page, and I do not (as far as I know!), have the ability to determine where in my controls this ID could be except by searching from Page downward.

The only thing I can think up is keeping a lookup table of every object on Page, but that seems like the wrong idea.

Has anyone else experienced this issue?

Upvotes: 6

Views: 1157

Answers (1)

CraigW
CraigW

Reputation: 715

Hrm, how about this ... The HtmlElementID should be the Client ID of the control which should hopefully be the fully qualified location of the control.

Something like this:

Page_Parent_0_Control_1

You could break up the ID string and then navigate from the page down to the control in question by piecing together the path to it.

Page findcontrol Page_Parent (index #0) Page_Parent_0 findcontrol Page_Parent_0_Control (index #1)

Still not the best way but it would save you from doing a shotgun search for the control in question.

Hopefully this will work for you or at least give you another way of looking at the problem :)

Upvotes: 2

Related Questions