Advanced UserControl stuff for easier customization

I put together this post on my old blog about 2 years ago and was recently asked questions about this tip. I figure it will get more readership on my MSDN blog, so here goes.


There are some great advantages of UserControls, but the favored advantage is the fact that it does not require recompilation of code to change the look & feel of content.

User controls are web controls. Let's say you want to do some sort of skinning on a user control? Here's a simple method to give your user controls a heading--like a web part heading. This code will give you the ability to skin the heading of your user control and allow you to place content within the user control on the ASPX page

[ParseChildren(true, "WebPartContent")]public class WebPart : UserControl { protected Label WebPartTitle; protected PlaceHolder WebPartContentPlaceholder; [Browsable(false)] public PlaceHolder WebPartContent { get { return WebPartContentPlaceholder; } set { WebPartContentPlaceholder = value; } } [Browsable(true)] public string Title { get { return WebPartTitle.Text; } set { WebPartTitle.Text = value; } }}

The ASCX control can look like this:

<div class="individual-layout">    <div class="heading">        <div class="heading-title"><asp:Label runat="server" id="WebPartTitle" /></div>        <div class="heading-collapse-button"><asp:Button runat="server" id="HideButton" /></div>    </div>    <div>        <asp:Placeholder runat="server" id="WebPartContentPlaceholder" />    </div></div>

And the ASPX page can look like this:

<body>    <uc:WebPart runat="server" Title="Web part title">    This is where my user control content will go...    </uc:WebPart></body>

How does this work? Someone recently asked me how this works. Well, it's important to understand webcontrol development to understand what's going on here. The [ParseChildren] attribute is giving the runtime a hint that the XML within my runat=server tag is really meant to be housed within another control. It acts like an XML schema <xs:any> tag and puts my content within my WebPartControlPlaceholder PlaceHolder's Controls collection. This is very similar to the way MasterPages are done in ASP.NET 2.0+.

Anyways, I thought it was a good tip.