Controls.Add() for a Web User Control doesn't instansiate its child controls

O

Ofer Zelig

I'll describe the simplest situation of the problem.

I have a simple Web User Control which only contains a: <div id="bla"
runat="server" /> .
I dynamically add it to a page, by performing:

SomeCtl ctl = new SomeCtl();
this.Controls.Add(ctl);

and of course apply a <% @ Register %> tag in order to make SomeCtl known to
the page (is there some more elegant way?).

I override OnPreRender of the control, in order to write some stuff to the
DIV according to some property of the control, but I can't (within the
event code) access the DIV. It is equal to null.
The issue happens of course only when my user control (SomeCtl) is added
dynamically to the page, and not when I place the user control directly
within the page at design time.


Thanks in advance for your help,
Ofer
 
M

Mark Rae

The issue happens of course only when my user control (SomeCtl) is added
dynamically to the page, and not when I place the user control directly
within the page at design time.

In which method are you adding the control...?

If you're doing it in Page_Load, try doing it in Page_Init instead...
 
O

Ofer Zelig

The host of that user control is a control itself (in this case, a
"regular", design-mode placed one).
I can't put it in Page_Init of the host control, because the code must
access properties of the control which are not available in its Page_Load
event yet...
 
M

Mark Rae

The host of that user control is a control itself (in this case, a
"regular", design-mode placed one).
OK.

I can't put it in Page_Init of the host control, because the code must
access properties of the control which are not available in its Page_Load
event yet...

In which case, you might find that you need to rethink your logic here a
bit, as I'm pretty sure the problem is that the dynamic creation of the
control is occurring too late in the overall page cycle...

I've seen this many times with dynamically created controls... Create them
in Page_Load, they sometimes work... Create them in Page_Init or
Page_PreInit, they always work...
 
O

Ofer Zelig

I can't see a way to change it...
As for the host control (design-time) - as I said, I can't run the
Controls.Add() at its Page_Init event (or any sooner event of course)
because the host control won't be able to access its properties. So it must
run at Page_Load, and in that case - runtime created control's child
controls are always null.
 
M

Mark Rae

I can't see a way to change it...
As for the host control (design-time) - as I said, I can't run the
Controls.Add() at its Page_Init event (or any sooner event of course)
because the host control won't be able to access its properties. So it
must
run at Page_Load, and in that case - runtime created control's child
controls are always null.

As I said, I think you'll have to redesign this piece of functionality
because I don't believe what you're trying to do is possible the way you
have architected it...
 
G

Guest

Howdy,

Web user controls have to be instantiated by calling LoadControl() method of
the page. Replace
SomeCtl ctl = new SomeCtl();
this.Controls.Add(ctl);

with:

// make sure path is correct
SomeCtl ctl = (SomeCtl) LoadControl("SomeControl.ascx");
this.Controls.Add(ctl);

Then, calling FindControl() will return valid HtmlGenericControl instance
representing your div. In addition, if you load controls programatically, you
don't need to use @Register directive on the page. It's only necessary if you
use put web user control in aspx code.

hope this helps
 
O

Ofer Zelig

Thanks Milosz & Walter, for your answer.

LoadControl actually did the job. "new" was the problem.

But - if I omit <% @ Register %> as Milosz suggested, code like SomeCtl ctl
= .... won't compile, because the page doesn't know SomeCtl without this
declaration.
I can write: Control ctl = LoadControl("SomeControl.ascx");
but in that case I won't be able to access ctl's members in the code... so
the only solution as I see would be placing a <% @ Register %> tag, or
declaring the control at the website level at web.config's <controls>
section.

Thanks!
 
W

Walter Wang [MSFT]

Hi Ofer,

Thanks for the update.

Yes LoadControl only returns a Control reference, to use the strong-typed
reference to the actual user control class, you will need to cast it and
you will need to import the namespace of the user control class.

To import the namespace, you will have two approaches: the first one is
doing it like what we do it in C#: put a using in your code. The second one
is yours: <% @ Regiser %> will help you import the namespace.

Actually there's third approach: use full qualified name of the user
control class.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
O

Ofer Zelig

Hello Mark,

A new thread has actually made it. The solution is to load the control by
LoadControl rather by SomeCtl ctl = new SomeCtl().
Thanks anyway!!

Ofer
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top