Dave Burke - Freelance .NET Developer specializing in Online Communities

A freelance .NET Developer

Controls in controls in controls [Updated - Solved! but ugly]

For a charity project I took the time to employ a barebones inheritance approach to web page design.  A basewebpage loads a basepagetemplate usercontrol which loads three page controls, one of which is the bodycontrol which itself loads one or more controls.  This allows me to isolate code to a single control, the only “new“ coding required for any given application.  This works great until I try to create an object reference between two controls loaded from the bodycontrol (which is loaded from the basepagetemplate control.)  As in

protected SiteNews sitenews;

Label lblNews = (Label) sitenews.FindControl("lblMenu");
lblNews.Text = "hello from Profile Control!";

...and many variants on the above code.

I can't seem to get past the “Object Reference not set to an instance of an object“ runtime error.

This is not something I have to do, just something I wanted to do to understand how to do it.  After several latenight hours I decided to put this on hold.  I GUESS it can be done, but since this quest was primarily an academic one, if it CAN be done I'll figure it out later.

So on the latenight R&D shelf for now: understanding how to talk between two controls deep in the loaded control heriarchy.

[UPDATE]

A big thanks to the guys who commented on this.  I thought about each comment, but what struck a chord was Scott Allen's statement that the control ID might be "munged" (that would be a soft "g").  Yes, when I had previously checked out the HTML source, I saw stuff like

<span id="_ctl0__ctl2_uc_sitenews_lblNews" class="mredstart"></span>

and knew I was seeing something related to the “object reference not set...” error.  So I grabbed the label's UNIQUEID property with lblNews.Text = lblNews.UniqueID.ToString().  It was something like

_ctl0:_ctl2:uc_sitenews:lblNews 

So I used the UniqueID with a Page.FindControl method, as in

Label.lblNews = (Label) Page.FindControl(”_ctl0:_ctl2:uc_sitenews:lblNews”);

which worked. 

As I said in the subject [update], this is ugly and it may in fact be wrong, but hey, it works.

In review, WHAT works?  I can now seem to reference any object in any control from any other control in a “multi-layered” inherited design with dynamically loaded control.  Sounds like a sweeping pronunciation, doesn't it?

 

Posted: Mar 14 2004, 05:03 PM by daveburke | with 6 comment(s)
Filed under:

Comments

MartinJ said:

I don't know, but have you tried calling EnsureChildControls() to make sure they are instantiated? It's just a quick thought.

-Martin
# March 14, 2004 5:55 PM

Scott Allen said:

Hi Dave:

Just two quick tips I hope can help:

There is a little snippet here to demonastrate how to loop through all the controls on a page: http://www.odetocode.com/Code/71.aspx

Also, if the control you are trying to find is inside of another control that implements INamingContainer (repeating controls like DataGrids), then the ID of the control is munged to make sure it is unique on the client (changed to something like "ctl0_lblMenu").

HTH,
# March 14, 2004 6:17 PM

AndrewSeven said:

You might only need to walk the tree a bit more. It depends a lot on how you build things up.

You might need SiteNews sitenews = Page.FindControl(sitenewsControl);
or
Parent.FindControl

If you have a commmon base class for all pages using the control, you can cast your control's .Page property as your base page type.
# March 14, 2004 6:44 PM

Dave Burke said:

Thanks everyone. It sounds like its possible and that I should stick with it. Scott, yes I was going to mention the "munging" of the control names. Here's an example:

<span id="_ctl0__ctl2_uc_sitenews_lblNews" class="mredstart"></span>

Martin, I had not heard of EnsureChildControls() before! Will investigate, but from the page source it appears they are. Andrew, I'll re-evaluate the casting in regards to the common base class. Thanks!
# March 14, 2004 8:38 PM

TrackBack said:

# April 22, 2004 11:48 PM

TrackBack said:

# April 23, 2004 12:00 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)