composite controls... Microsoft Press: Dev ASP.NET Server Controls

D

dx

I have the Microsoft Press: Developing Microsoft ASP.NET Server Controls and
Components book. It's starting to shine some light on control development
but there is something about composite controls that I don't understand...
I've included a snippet from Chapter 12 below on Composite Controls:

<start>

Override the CreateChildControls method to instantiate child controls,
initialize them, and add them to the control tree. Do not perform this logic
in the constructor or in the OnInit method.

Let's examine the reason for this implementation detail. You must create
your child controls in the CreateChildControls method--instead of creating
them in a specific phase such as Instantiate or Initialize--so that children
can be created on demand when needed in your control's life cycle. This is
especially important when you create composite controls whose child controls
handle postback data.

<end>

I do not understand this at all. It seems to me that the Init method would
be a safe place to initialize the child objects since that method occurs
before loading postback data or raising postback events (in the control life
cycle.) What am I missing here?

Much Thanks in advance.

Stan
 
P

Pete Beech

I've often wondered the same - and there are some people who don't bother
with CreateChildControls at all - see
http://www.wilsondotnet.com/Tips/ViewPosts.aspx?Thread=278 .

Possibly its only useful in the case that the child controls change as a
result of the postback (e.g. the expanding of a node in a simple serverside
treeview control) - then, you can just set ChildControlsCreated = false to
get them recreated (the next time EnsureChildControls is called.).

I can't quite see at first glance why "this is especially important when you
create composite controls whose child controls handle postback data.".
Presumably, to get viewstate loaded, and postback data also, you would need
to make sure EnsureChildControls was called in OnInit anyway - so why can't
you just create them in OnInit.

Maybe its more of a mini design pattern type thing - i.e., perhaps the
ASP.NET designers considered a control whose child controls remain static
(i.e. the actual objects in the Controls collection don't need to change
based on some postback event or value) as a special case, and the more
general case is that the Controls collection could vary on each postback. So
they might have thought this is best handled by a separate function
CreateChildControls, rather than coding directly in OnInit, and so tried to
enforce this as a best practice.

Its a very interesting question!
Cheers,
Pete Beech
 
J

John Saunders

dx said:
I have the Microsoft Press: Developing Microsoft ASP.NET Server Controls and
Components book. It's starting to shine some light on control development
but there is something about composite controls that I don't understand...
I've included a snippet from Chapter 12 below on Composite Controls:

<start>

Override the CreateChildControls method to instantiate child controls,
initialize them, and add them to the control tree. Do not perform this logic
in the constructor or in the OnInit method.

Let's examine the reason for this implementation detail. You must create
your child controls in the CreateChildControls method--instead of creating
them in a specific phase such as Instantiate or Initialize--so that children
can be created on demand when needed in your control's life cycle. This is
especially important when you create composite controls whose child controls
handle postback data.

<end>

I do not understand this at all. It seems to me that the Init method would
be a safe place to initialize the child objects since that method occurs
before loading postback data or raising postback events (in the control life
cycle.) What am I missing here?

Why do you think you _want_ to initialize the child objects in the Init
event?

Child controls should be instantiated when they are needed, and not before.
You probably don't need them up in the Init event.
 
P

Pete Beech

For viewstate to be loaded into the composite control (assuming each
subcontrol has it enabled) wouldn't you need to make sure they are created
in OnInit - either by using EnsureChildControls or creating them explicitly?
I would think that's a reason to have them created up in the Init event.

What is the disadvantage of creating the controls explicitly in OnInit,
assuming the structure of the controls is static and will never change? Why
is the passage in the book warning against this?

I'm convinced there must be a good reason for this, but I can't really see
it..

Pete
 
S

Scott

I think you have partially answered your own question; the method EnsureChildControls is tied to
the idea that child controls will be created in the CreateChildControls; so if you plan on using
EnsureChildControls, for example in a property of the composite control, you should create the child
controls in CreateChildControls (because EnsureChildControls will not result in OnInit being called,
but is will make sure CreateChildControls is called).

So, when you see something like:

public string Foobar {
get { EnsureChildControls(); return Child.Foobar; }
set { EnsureChildControls(); Child.Foobar = value; }
}

Now you are using the facilities provided by the class library; if you create the child controls in
OnInit, creating property like the above would be trickier (you'd have to eventually get the child
creation out into a separate method -- which gets you right back to CreateChildControls).

Of course, the control framework is clever enough to do "catch ups"; so you can create child
controls in all kinds of places and have it "work"; but if you want take advantage of
EnsureChildControls (as well as ChildControlsCreated, etc. etc. etc.) you "should" create children
in CreateChildControls.

Now, the book also goes on to say that you should also override the Controls collection property;
and now we are beginning to deal with getting the viewstate up and working.

My two cents,
Scott


Pete Beech said:
For viewstate to be loaded into the composite control (assuming each
subcontrol has it enabled) wouldn't you need to make sure they are created
in OnInit - either by using EnsureChildControls or creating them explicitly?
I would think that's a reason to have them created up in the Init event.

What is the disadvantage of creating the controls explicitly in OnInit,
assuming the structure of the controls is static and will never change? Why
is the passage in the book warning against this?

I'm convinced there must be a good reason for this, but I can't really see
it..

Pete
 
P

Pete Beech

I can see how the CreateChildControls/EnsureChildControls mechanism works,
but I still don't see the point (at least for controls with a fixed set of
unchanging ChildControls). Assuming no property ever gets called before
OnInit (which maybe is an assumption which you can't make - although I can't
see why not), then creating them in OnInit should be adequate.

So, in your example, if Foobar was always called after the OnInit, there's
no problem.

The thing is, the book makes out the creation of controls in OnInit to be
dangerous - and the only clue is that it "is especially important when you
create composite controls whose child controls handle postback data.". But
what exactly is the problem? What wouldn't work if you did it just in
OnInit? Do the child controls, as part of handling the postback data,
request that the parent control recreates all its child controls for some
reason? (maybe I need to use Anakrino)

It seems, from searching the newsgroups and forums, that a lot of people
just create their child controls in OnInit anyway, and never have any
problems.

Pete
 
S

Scott

Yes; I did say that you could create controls in lots of places, and ASP.NET will play catch-up and
things will work. When I started writing composite controls, I created all my child controls in
OnInit or a helper method -- however, this quickly began to break down -- I've given one specific
case, the forwarding of properties to a child controls. When you start writing designers things get
more complicated if you don't play along with the control framework.

Perhaps I should have provided more details about the Foobar property; I can easily see a situation
when I would instantiate a composite control object and set some properties before I associate the
control with a parent -- actually, I do this all the time.

As far as the particular language, it seems a little draconian; and if you really want an answer
about the authors choice of words I think Nikhil Kothari has a blog someplace -- maybe you can post
a comment there.

Scott
 
P

Pete Beech

Thanks for that - thats a good point, setting properties before adding to
the parent, when they're forwarded properties. It would be interesting to
try out some of these controls that have been written using just OnInit to
see if they do have the kind of problems you mention.

Cheers,
Pete

Scott said:
Yes; I did say that you could create controls in lots of places, and ASP.NET will play catch-up and
things will work. When I started writing composite controls, I created all my child controls in
OnInit or a helper method -- however, this quickly began to break down -- I've given one specific
case, the forwarding of properties to a child controls. When you start writing designers things get
more complicated if you don't play along with the control framework.

Perhaps I should have provided more details about the Foobar property; I can easily see a situation
when I would instantiate a composite control object and set some
properties before I associate the
control with a parent -- actually, I do this all the time.

As far as the particular language, it seems a little draconian; and if you really want an answer
about the authors choice of words I think Nikhil Kothari has a blog
someplace -- maybe you can post
 
C

ccallen

Scott alludes to an important tactic, just try it out and find out where it
breaks (build up your experience). This is great if periodic downtime is ok.
However, if downtime on the production machine (due to the control failing)
is somthing you want to avoid, then the CreateChildControls method is the
safe bet (from a negligence point of view). Another reason to stick with the
documented guidelines is that things may change in the next version. Of
course the documented method could change, but if your on the beta you can
catch the changes before you customers do.

ccallen

Scott said:
Yes; I did say that you could create controls in lots of places, and ASP.NET will play catch-up and
things will work. When I started writing composite controls, I created all my child controls in
OnInit or a helper method -- however, this quickly began to break down -- I've given one specific
case, the forwarding of properties to a child controls. When you start writing designers things get
more complicated if you don't play along with the control framework.

Perhaps I should have provided more details about the Foobar property; I can easily see a situation
when I would instantiate a composite control object and set some
properties before I associate the
control with a parent -- actually, I do this all the time.

As far as the particular language, it seems a little draconian; and if you really want an answer
about the authors choice of words I think Nikhil Kothari has a blog
someplace -- maybe you can post
 
P

Pete Beech

Thanks, but of course, that's what I always do. In this case since I've
never had it break it down on me, nor have people like Paul Wilson (see
http://www.wilsondotnet.com/Tips/ViewPosts.aspx?Thread=278 ). So, here I'm
just trying to understand the reasoning behind it, and the reasoning given
in the passage from the book that the original poster quoted. which still
doesn't make sense to me yet.
 
J

John Saunders

Pete Beech said:
I can see how the CreateChildControls/EnsureChildControls mechanism works,
but I still don't see the point (at least for controls with a fixed set of
unchanging ChildControls). Assuming no property ever gets called before
OnInit (which maybe is an assumption which you can't make - although I can't
see why not), then creating them in OnInit should be adequate.

First the parent control is instantiated, then the properties are set, then
OnInit gets called. If any parent properties are in any way dependent on
child controls, or if any child controls are dependent on parent properties,
then OnInit is too late. This is especially true if the set of child
controls depends on parent properties.
 

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

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top