ASP.NET 4 in Practice - Composite Controls
This article is based on ASP.NET 4.0 in Practice published on May 15, 2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information.
![]() |
ASP.NET 4 in Practice
By Daniele Bochicchio, Stefano Mostarda, and Marco De Sanctis Custom controls are often created by combining existing ones, enhancing their features. Combining controls is more challenging than creating a new one from scratch. In this article from the book ASP.NET 4.0 in Practice, you’ll learn how to how to build composite controls using ASP.NET. |
Custom controls are often created by combining existing ones, enhancing their features. In most situations, this process consists of picking two or more controls and combining them to produce a single result. Knowing how to do this is important because you can reuse existing controls and add more features to simplify the use of common, recurring situations.
Combining controls is more challenging than creating a new one from scratch. When you create composite controls, you’ll encounter special problems. For example, the controls need to be wrapped, and their members need to be exposed in the corresponding control. This task is simple to perform but it’s also time consuming. The reality is that you’ll map only the most used and useful members and add the others as you need them.
The problem with this class of controls is that you’re hiding them from the outside, deciding what the external world may and may not use. For this reason, events handled internally by these controls can become a nightmare. You need to implement an event bubbling technique (to let events propagate through the control tree), or opt to define new events to expose just the existing ones outside the wrapped controls. To fully understand how all this will affect how you create a composite control, our scenario will cover how to build composite controls using ASP.NET.
Problem
Let’s suppose you need to create a special DropDownList
that,
in a single declaration, can be used to both insert the description and the
options to be selected by the user.
By using this control, you can save a lot of time in terms of markup to be written, and you can reuse the same feature over and over in your projects.
Solution
Composite controls are generally created by
deriving from CompositeControl
in System.Web.UI.WebControls
.
This class implements a lot of the logic necessary to implement custom controls
that are web controls, too—composite controls support styling, for example. If
you don’t need these features, you can opt for the simple Control class from System.Web.UI
.
Using the Control class
will ensure that the generated markup remains simple, but you’ll need to
manually add the missing features that Composite-Control already provides.
Figure 1 illustrates the concept of composite controls. Whether
you use the CompositeControl
class or the Control
class, you need to manipulate the page’s control tree and
dynamically instantiate controls at runtime.
Composite controls work by combining controls together, so the
controls are added using the CreateChildControls
method.
The CreateChildControls
method is called via a call to the EnsureChildControls
method
whenever a child control is needed. When you’re manipulating the control tree,
you need to be careful and remember that these are controls that will be nested
into the control itself and then into the page. To add a control inside
another, you have to access its Controls properties and add it via the Add method, as
shown in the following listing.
Listing 1 CreateChildControl contains the Nested Controls Declaration
C#
public class SuperDropDownList: CompositeControl, INamingContainer
{
protected override void CreateChildControls()
{
if (ChildControlsCreated) #1
return;
Controls.Clear(); #A
Controls.Add(new LiteralControl("<p>"));
Label labelText = new Label();
labelText.Text = Description;
Controls.Add(labelText);
Controls.Add(new LiteralControl(
string.IsNullOrEmpty(Description)?
string.Empty:": "));
DropDownList listControl = new DropDownList();
Controls.Add(listControl);
Controls.Add(new LiteralControl("</p>"));
ChildControlsCreated = true; #1
}
... #B
}
VB
Public Class SuperDropDownList
Inherits CompositeControl
Implements INamingContainer
Protected Overrides Sub CreateChildControls()
If ChildControlsCreated Then #1
Return
End If
Controls.Clear() #A
Controls.Add(New LiteralControl("<p>"))
Dim labelText As New Label()
labelText.Text = Description
Controls.Add(labelText)
Controls.Add(New LiteralControl(If(String.IsNullOrEmpty(Description),
String.Empty, ": ")))
Dim listControl As New DropDownList()
Controls.Add(listControl)
Controls.Add(New LiteralControl("</p>"))
ChildControlsCreated = True #1
End Sub
... #B
End Class
#1 Avoids control creation
#A Removes existing controls
#B Continues code
As you can see in this listing, we’re basically adding some
controls in order to display a DropDownList
and a description. To remove unwanted
controls from the control tree (which could be Literal
controls that can be added in
markup), we’re performing a call to Controls.Clear
to reset the control tree.
The code in #1 isn’t actually necessary because it’s already included
by Composite-Control
.
Listing 1 shows how to deal with this problem when another simpler base control
(as Control)
is used. Look at figure 2 to see the results.
We’ve omitted the declaration of the properties from listing 1 for brevity. When you need to set the properties for the inner controls, you have to use a special approach: you need to access an inner object’s property from outside the control. In these situations, the preferred way to go is shown in the following snippet:
C#
public IList DataSource
{
get
{
EnsureChildControls(); #A
return ((DropDownList)Controls[3]).DataSource as IList;
}
set
{
EnsureChildControls();
((DropDownList)Controls[3]).DataSource = value;
}
}
VB
Public Property DataSource() As IList
Get
EnsureChildControls()
Return TryCast(DirectCast(Controls(3), DropDownList).DataSource, IList)
End Get
Set
EnsureChildControls() #A
DirectCast(Controls(3), DropDownList).DataSource = value
End Set
End Property
#A Will call CreateChildControls
As you can see, we’re referring to the control we created in
listing 1 (in this case, the DropDownList
), finding it by position, and directly
exposing its inner property. Because you don’t have to keep the inner property
in sync (it’s automatically performed using this pattern), this example shows
you the best way to handle this situation.
HOW TO AVOID REFERENCING A CONTROL BY POSITION To produce cleaner code, you can also save a reference to the controls in CreateChildControls and then refer to the controls using this syntax (instead of finding them by position).
The calls to EnsureChildControls
are not only important—they’re mandatory. These calls ensure that
the controls are created before we access them.
Now that the infrastructure of our control is in place, let’s take a look at how to use events in composite controls.
Events in Composite Controls
Events are used in custom controls to simplify the code necessary to handle a state. A composite control hides the child controls, so you need to propagate their events outside the container by implementing an event wrapper.
Redirecting an event is a simple technique. The event is sent outside by first intercepting it locally and then propagating it outside. Take a look at the following snippet to understand how it works. In this case, the code is worth 1,000 words.
C#
public event EventHandler SelectedValueChanged;
protected void OnSelectedValueChanged(EventArgs e)
{
if (SelectedValueChanged != null)
SelectedValueChanged(this, e);
}
VB
Public Event SelectedValueChanged As EventHandler
Protected Sub OnSelectedValueChanged(e As EventArgs)
RaiseEvent SelectedValueChanged(Me, e)
End Sub
This snippet will expose a new event,
called SelectedValueChanged
, and a new OnSelectedValueChanged
method, which is used to define the
event handler in the markup. The last addition we need to make in order to
attach the event to the inner control is to add this simple code in the CreateChildControls
method,
right after the DropDownList
instance:
C#
DropDownList listControl = new DropDownList();
listControl.SelectedIndexChanged += (object sender, EventArgs e) => {
OnSelectedValueChanged(e);
};
VB
Dim listControl as New DropDownList()
listControl.SelectedIndexChanged += Function(sender As Object,
e As EventArgs) Do
OnSelectedValueChanged(e)
End Function
This snippet ensures that when the DropDownList
’s SelectedIndexChanged
event is fired, our
event will be fired, too. The result is that the event handler created inside
the page will also be called, and our event will propagate outside the
contained control.
Discussion
When you’re building composite controls, you need to pay
attention to the fact that you’re not generating markup, but composing your
controls, mixing them together, and manipulating the page’s control tree. This
task is certainly easy to implement in a simple scenario like the one we
covered here because you’re leveraging existing controls but it can also be
prone to error. As you’ve learned in this scenario, you need to understand how CreateChildControls
and EnsureChildControls
work.
Summary
Getting started with custom controls isn’t difficult, but advanced scenarios involve a deep understanding of ASP.NET. In more simple situations, custom controls can help you avoid code duplication by implementing and supporting repetitive tasks. You can easily add PostBack and templates to every control, and implementing support for data binding isn’t all that difficult.
Here are some other Manning titles you might be interested in:
![]() |
ASP.NET MVC 2 in Action
|
![]() |
ASP.NET AJAX in Action |
![]() |
IronRuby in Action
|
Post Comment
fvvTCX Keep up the superb piece of work, I read few posts on this website and I believe that your web site is really interesting and has got circles of superb information.
I constantly spent my half an hour to read this blog's content all the time along with a cup of coffee. morme.aperca.se/map3.php gГҐr man ner i vikt av diarre
I'm not sure why but this website is loading extremely slow for me. Is anyone else having this problem or is it a problem on my end? I'll check back later on and see if the problem still exists. ena benet svullet otertbe.se/map25.php
I was able to find good advice from your content. stagc.aperca.se/map3.php necessär från victoria secret
I am really delighted to read this web site posts which contains tons of helpful information, thanks for providing such information. peugeot 208 bagageutrymme oratrg.se/map30.php
Good blog you've got here.. It's difficult to find high-quality writing like yours nowadays. I truly appreciate people like you! Take care!! mahi.munhea.se/map5.php face cream for black skin
My relatives always say that I am wasting my time here at web, but I know I am getting knowledge everyday by reading such good content. mysub.aperca.se/map5.php abecita alanya bikini
Hello There. I discovered your weblog the usage of msn. That is an extremely neatly written article. I'll be sure to bookmark it and return to learn extra of your useful info. Thanks for the post. I'll definitely comeback. sasilu.se/map23.php köpa grus västervik
It's perfect time to make a few plans for the long run and it's time to be happy. I've read this publish and if I may I wish to suggest you some fascinating issues or suggestions. Maybe you can write next articles referring to this article. I desire to read even more issues approximately it! cator.munhea.se/map2.php tjockare Г¶gonbryn serum
I always used to study piece of writing in news papers but now as I am a user of internet therefore from now I am using net for posts, thanks to web. sasilu.se/map31.php mamma teresa meny
I'm more than happy to discover this great site. I need to to thank you for ones time for this wonderful read!! I definitely liked every bit of it and I have you bookmarked to see new information in your website. match.aperca.se/map1.php hundens næse løber
Tremendous things here. I am very satisfied to look your article. Thanks so much and I'm taking a look forward to touch you. Will you kindly drop me a mail? cella.munhea.se/map13.php när är matchen ikväll
I am really inspired together with your writing skills and also with the layout for your blog. Is that this a paid subject matter or did you modify it your self? Anyway stay up the nice quality writing, it is rare to peer a nice blog like this one nowadays.. otertbe.se/map24.php sollentuna energi jour
I blog often and I truly thank you for your content. This great article has truly peaked my interest. I will book mark your website and keep checking for new information about once per week. I subscribed to your Feed too. panilul.se/map8.php krГёlle hГҐr med glattejern
Wonderful post! We will be linking to this particularly great article on our site. Keep up the good writing. dehllap.se/map34.php urinvägsinfektion känns som mensvärk
Great goods from you, man. I've understand your stuff previous to and you're just extremely wonderful. I really like what you've acquired here, really like what you're saying and the way in which you say it. You make it entertaining and you still take care of to keep it sensible. I can't wait to read far more from you. This is really a tremendous website. liest.munhea.se/map3.php vätskefylld blåsa i munnen
Hi, I do think this is a great web site. I stumbledupon it ;) I may come back once again since I book marked it. Money and freedom is the best way to change, may you be rich and continue to guide other people. sasilu.se/map9.php uppgifter om fГ¶retag
It's in reality a great and useful piece of information. I am happy that you simply shared this useful information with us. Please keep us up to date like this. Thanks for sharing. panilul.se/map26.php kap verde i oktober
Thanks to my father who shared with me about this webpage, this blog is truly awesome. sgemr.munhea.se/map11.php Г¤lvar i dalarna
I’m not that much of a internet reader to be honest but your blogs really nice, keep it up! I'll go ahead and bookmark your site to come back later on. Cheers azilopar.se/map29.php philips sonicare dual pack
I am regular reader, how are you everybody? This paragraph posted at this web site is genuinely nice. benmmdi.se/map13.php styr bГҐt korsord
That is a very good tip especially to those fresh to the blogosphere. Short but very precise info… Many thanks for sharing this one. A must read article! oreiep.se/map10.php grГёnt hГҐr pool
This is a great tip particularly to those fresh to the blogosphere. Brief but very accurate information… Appreciate your sharing this one. A must read post! munhea.se/map11.php linas matkasse pris
My brother suggested I might like this web site. He was once entirely right. This publish truly made my day. You cann't imagine simply how much time I had spent for this info! Thank you! probduo.se/map4.php grus i Г¶gonen pГҐ morgonen
Good day! Do you know if they make any plugins to help with SEO? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good success. If you know of any please share. Many thanks! prosd.aperca.se/map6.php billiga sneakers nike
Your mode of telling all in this post is actually nice, every one be able to simply be aware of it, Thanks a lot. oratrg.se/map31.php tjock fläskpannkaka ugn
Hi friends, how is all, and what you desire to say on the topic of this post, in my view its in fact remarkable designed for me. masco.munhea.se/map3.php accelerator tanning lotion
Touche. Outstanding arguments. Keep up the great spirit. persdap.se/map35.php polyp i livmodern cancer
each time i used to read smaller content which as well clear their motive, and that is also happening with this paragraph which I am reading now. stagc.aperca.se/map4.php bake off brГ¶d recept
Good post but I was wanting to know if you could write a litte more on this topic? I'd be very grateful if you could elaborate a little bit further. Bless you! mondd.munhea.se/map4.php clear brain pris
I like the valuable information you provide in your articles. I'll bookmark your weblog and check once more right here regularly. I am somewhat certain I'll learn many new stuff right here! Best of luck for the next! dehllap.se/map9.php boeuf bourgogne recept
When I initially left a comment I seem to have clicked on the -Notify me when new comments are added- checkbox and now every time a comment is added I receive 4 emails with the same comment. Perhaps there is an easy method you can remove me from that service? Thanks! derse.aperca.se/map1.php ont i brГ¶sten pms
What's up, this weekend is nice in favor of me, for the reason that this occasion i am reading this great educational post here at my home. oratrg.se/map18.php rut rot avdrag
Why users still make use of to read news papers when in this technological world all is accessible on web? spare.aperca.se/map2.php värk i näsan
Hi there! I could have sworn I've visited this blog before but after going through some of the articles I realized it's new to me. Anyways, I'm definitely delighted I came across it and I'll be book-marking it and checking back often! sasilu.se/map8.php telia och viasat
Hey I am so glad I found your weblog, I really found you by error, while I was searching on Askjeeve for something else, Anyhow I am here now and would just like to say kudos for a incredible post and a all round interesting blog (I also love the theme/design), I don't have time to go through it all at the minute but I have saved it and also added your RSS feeds, so when I have time I will be back to read more, Please do keep up the excellent job. linkm.aperca.se/map4.php gГ¶ra rent ugn
Way cool! Some extremely valid points! I appreciate you penning this article and the rest of the website is also really good. mondd.munhea.se/map5.php partykungen gГ¶teborg Г¶ppettider
Hello, i think that i saw you visited my blog thus i came to “return the favor”.I am trying to find things to improve my web site!I suppose its ok to use a few of your ideas!! oreiep.se/map32.php tofflor dam ГҐhlens
If you would like to obtain much from this piece of writing then you have to apply such techniques to your won webpage. tread.aperca.se/map4.php bГ¶rja Г¤ta lchf
Hey! Do you know if they make any plugins to help with Search Engine Optimization? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good gains. If you know of any please share. Kudos! egluopu.se/map12.php stor hjärnblödning prognos
you are in point of fact a just right webmaster. The website loading pace is amazing. It sort of feels that you're doing any unique trick. In addition, The contents are masterpiece. you have performed a magnificent task in this topic! dehllap.se/map33.php ek service hГ¶rby
Hi, I do believe this is a great web site. I stumbledupon it ;) I'm going to return yet again since I book-marked it. Money and freedom is the greatest way to change, may you be rich and continue to help others. nistm.munhea.se/map5.php mejerifri lchf meny
This is a great tip particularly to those fresh to the blogosphere. Simple but very precise information… Appreciate your sharing this one. A must read post! benmmdi.se/map14.php hur mycket Г¤r 600 kalorier
Wow that was strange. I just wrote an extremely long comment but after I clicked submit my comment didn't show up. Grrrr... well I'm not writing all that over again. Anyhow, just wanted to say superb blog! morme.aperca.se/map6.php kyl frys test
This information is priceless. Where can I find out more? azilopar.se/map12.php sätt att gå ner i vikt
bookmarked!!, I love your web site! squgarik.se/map28.php chokladkalender med tryck
Hi there friends, how is everything, and what you wish for to say about this article, in my view its really remarkable for me. panilul.se/map16.php ta bort svettfläckar med ättika
I do not even understand how I finished up right here, however I thought this publish was great. I don't understand who you're but certainly you're going to a well-known blogger in case you are not already. Cheers! viesu.munhea.se/map5.php gamla svenska ord
Hello, this weekend is nice designed for me, as this occasion i am reading this enormous informative piece of writing here at my home. azilopar.se/map1.php overgangsalder smerter i underlivet
Heya i am for the primary time here. I came across this board and I in finding It truly useful & it helped me out much. I am hoping to provide something back and help others like you helped me. azilopar.se/map7.php bring freight forwarding ab