Classic ASP had to rely on include files or COM components to provide reusable functionalities. A classic example of reusable functionalities through the use of include files was an HTML menu which was displayed on each Web page. Although include files can still be used in ASP.NET, ASP.NET now solves the issue of reusable code by introducing custom controls. Custom controls can be loaded at run time to expose a rich set of functionality that can be used on every ASP.NET page. Furthermore, each user control lives in its own sandbox, enabling each control to use any variable name without the possibility of name conflicts with any other control.
ASP.NET custom controls sound like ActiveX components, but in fact, both are quite different. For example, ActiveX controls are built as .ocx files and are available for download. However, one of their downfalls is that ActiveX controls had to be downloaded before the user could see or use the page on which the ActiveX control was on. Also, ActiveX controls are only supported on IE, whereas other browsers would need a plug-in to correctly use them.
On the other hand, custom controls can be either compiled manually by the developer or they can be Just-In-Time compiled on the Web server. The custom control's output is rendered by the .NET Framework on the Web server as HTML. This means there is no file to download or no browser compatibility to worry about!
Currently ASP.NET has two types of custom controls:
A user control is identified through its .ascx file extension. In its simplest form, a user control is nothing more than HTML contained in a separate file that is dynamically included in an ASP.NET page when a page request is processed. This is very similar to classic ASP text files.
A real-world example of a very basic user control is the copyright message that appears at the bottom of most Web pages. Rather than duplicating this HTML on every ASP.NET page file, a user control with the appropriate HTML is created and this user control is associated with each ASP.NET page that required this copyright message. Because the copyright content exists in one file, it can be changed centrally ensuring that all pages who use this control are updated automatically. Another real-world example would be a rating control used to rate the content of each article or page.
How do you write a user control? The simplest way is to use Visual Studio.NET to create a Web User Control. The following demonstrates a very simple user control
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="Copyright.ascx.cs"
Inherits="UserControls.Copyright" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<P>This is my copyright message</P>
The Page directives will be explained later on, but more importantly, note that Web user controls do not contain <html> or <body> tags simply because Web user controls will be included in a Web Form that already contains those tags. Additionally, server-side form tags <form runat="server></form> should not be included, because a Web Form is only allowed one server-side form. However, if you need to take advantage of server-side PostBack functionality in your Web user control, declare an instance of your user control between the <form runat="server></form> tags on the Web form.
If a Web Form is being converted into a Web user control, then the @Page directive must be converted to a @Control directive. The @Control directive supports all functionality supported by the @Page directive except for the Trace attribute. Tracing cannot be enabled for user controls.
In order to user a User Control in an ASP.NET Web Form, it must first be registered. Registering a User Control means adding the @Register directive to fully identify the user control (name and path) . The @Register directive takes three attributes: TagPrefix, TagName, and Src. The first attribute identifies which prefix to use when adding the user control, the second attribute is the name of the control, and the third attribute identifier the relative path the .ascx file. The @Register directive must be added to the top of each ASP.NET page that wants to use that User Control. A typical @Register directive looks like:
<%@ Register TagName="Copyright" TagPrefix="dt" Src="/controls/Copyright.ascx" %>
Now once the User Control has been registered, it can be placed any where on the ASP.NET Web Form in the same fashion you would for any built-in control. The syntax would be:
<tagprefix:tagname id="copyright1" runat="server" />
A User Control can have any number of instances in a Web Form, with each instance running in its own sandbox, protecting the Web Form from any naming conflicts. The following shows an example of an ASP.NET Web Form using a User Control:
<%@ Register
TagPrefix="uc1" TagName="Copyright" Src="Copyright.ascx" %>
<%@ Page language="c#" Codebehind="default.aspx.cs" AutoEventWireup="false" Inherits="UserControls.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
...
<HEAD>
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post"
runat="server">
<uc1:Copyright id="Copyright1" runat="server"></uc1:Copyright>
</form>
</body>
</HTML>
The true strength of User Controls comes from their ability to expose properties and methods in a true object-oriented way. Like any .NET object, the User Control can expose inherited properties and methods or custom properties and methods as shown below:
A User Control derives from the following classes as shown below:

As a result of this class hierarchy, a User Control will have a rich set of inherited (or inherent) properties and methods.
Custom properties and methods can be used to perform operations and retrieve/set values meaningful to the User Control instance. However, note that a User Control can expose properties in two ways:
The general approach here is that you create a User Control and modify its code behind module by adding public variables. These public variables can then be specified at design time in the ASP.NET Web Form hosting the User Control. In the following example, note how the strAddress public property in the User Control's code behind module can be accessed and specified in the ASP.NET Web Form.
<!-- User Control HTML content
-->
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="UC_pubvars.ascx.cs" Inherits="UserControls.UC_pubvars" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<P>
< asp:Label id="lblAddress" runat="server" Width="363px">Label</asp:Label>
</P>
/* Code behind module associated
with the User Control. Note how the strAddress public property is used to
initialze other components of the User Control (a label) */
public abstract class UC_pubvars : System.Web.UI.UserControl
{
/* Data members */
protected System.Web.UI.WebControls.Label lblAddress;
// Public variables. Can be set as properties in the page's HTML at design time
public string strAddress;
private void Page_Load(object sender, System.EventArgs e)
{
lblAddress.Text = strAddress;
}
#region Web Form Designer generated code
...
#endregion
}
<%@ Page language="c#" Codebehind="Page_pubvars.aspx.cs" AutoEventWireup="false" Inherits="UserControls.Page_pubvars" %>
<%@ Register TagPrefix="uc1" TagName="UC_pubvars" Src="UC_pubvars.ascx" %>
...
<HTML>
<HEAD>
...
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Page_pubvars" method="post" runat="server">
<uc1:UC_pubvars id="address" runat="server"
strAddress="123 DotNet Street, SunnyVale, NT"></uc1:UC_pubvars>
</form>
</body>
</HTML>

Although public variables are easy to use, they do not provide the ability to execute code. It can only be used to get/set a value. Properties are more appropriate when you want to set/get a value and perform some action as well. For example, the set part of a property can be used to validate input before actually using it. An example of such a case is a property that accepts a Date/Time value. The set part of the property can then ensure that the given date is not more than 10 days earlier than the current date, for example. Another example would be for the User Control to retrieve a user's address once the ID property has been set. Therefore, using properties allows you to create rich functionality that only execute when Set or Get are fired. While the following code examples illustrate the usage of properties, the same coding approach applies to using methods:
<!-- User control. Contains two
bordered labels -->
<%@ Control Language="c#" Codebehind="UC_pubvars.ascx.cs"
Inherits="UserControls.UC_pubvars"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<P><asp:label id="lblStreet" Width="363px" runat="server" BorderStyle="Groove">Street Address</asp:label></P>
<P><asp:Label id="lblCity" Width="363px" runat="server" BorderStyle="Groove">City Address</asp:Label></P>
<!-- Code behind for the User
Control.
Note that public variables of this class can will be identified as attributes of
this control in the HTML file of the page containing this control. Also note the
use of the UserID property that is called by code behind module of the page
containing this user control -->
namespace UserControls
{
using ...
public class UC_pubvars : System.Web.UI.UserControl
{
/* Data members */
private int nID;
protected System.Web.UI.WebControls.Label lblStreet;
protected System.Web.UI.WebControls.Label lblCity;
// Public variables. Can be set as properties in the page's HTML at design time
public string strStreet;
public string strCity;
private void Page_Load(object sender, System.EventArgs e)
{
// Used to set street and city values to those initialized by the hosting page
lblStreet.Text = strStreet;
lblCity.Text =
strCity;
}
// This
property gets called by the container page
public int UserID
{
set
{
// Get the value
nID = value;
// Lookup the address associated with this ID through some database
// ...
strStreet = "123 DotNet Blvd";
strCity = "SunnVale, NT";
// Now set the address label
lblStreet.Text = strStreet;
lblCity.Text = strCity;
}
}
#region Web Form Designer generated code
...
#endregion
}
}
<!-- The actual ASP.NET page
containing the user contorl. Note that content is arranged within a table (for
presentation purposes) -->
%@ Page language="c#" Codebehind="Page_pubvars2.aspx.cs" AutoEventWireup="false" Inherits="UserControls.Page_pubvars2" %>
<%@ Register TagPrefix="uc1" TagName="UC_pubvars" Src="UC_pubvars.ascx" %>
<HTML>
<HEAD>
...
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Page_pubvars2" method="post" runat="server">
<TABLE id="Table1" cellSpacing="0" cellPadding="0" width="400" border="0">
<TR>
<TD style="HEIGHT: 130px">
<uc1:UC_pubvars id="UC_pubvars1" runat="server"></uc1:UC_pubvars>
</TD>
</TR>
<TR>
<TD style="HEIGHT: 62px">
<asp:label id="Label1" runat="server" Width="106px">Enter User ID</asp:label>
<asp:TextBox id="txtUID" runat="server" Width="121px"></asp:TextBox>
<asp:Button id="btnLookupAddress" runat="server" Width="79px" Text="Lookup"></asp:Button>
</TD>
</TR>
</TABLE>
</form>
</body>
</HTML>
// Code behind module for the
container page
using System;
using ...
namespace UserControls
{
public class Page_pubvars2 : System.Web.UI.Page
{
/* Data members
*/
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.TextBox txtUID;
protected System.Web.UI.WebControls.Button btnLookupAddress;
protected UC_pubvars UC_pubvars1;
private void Page_Load(object sender, System.EventArgs e)
{
UC_pubvars1.strCity = "------";
UC_pubvars1.strStreet = "------";
}
#region Web Form Designer generated code
...
endregion
/* User
submitted the form. Sebd user ID to the user control to look up and display the user's
address */
private void btnLookupAddress_Click(object sender, System.EventArgs e)
{
UC_pubvars1.UserID = Int32.Parse(txtUID.Text);
}
}
}
The following is the output. The address user control can now be used by any page - same look and feel and same class interface.


As shown above, user controls are just object instances of the UserControl class. Just like any other ASP.NET objects, user controls can be dynamically loaded at runtime. With dynamic loading, you build the Web page on the fly based on user-specified parameters.
As a rule of thumb, any object that exposes the Controls collection can have controls added to it dynamically. For example, the following code illustrates how to add a control to the list of controls maintained by the Page class:
Page.Controls.Add( obSomeControl );
The following example illustrates how to load the address user control created in the previous section.
public class Page_dynload : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
// Load the control and add it to this page
UC_pubvars obUC = (UC_pubvars)LoadControl( "UC_pubvars.ascx" );
this.Controls.Add( obUC );
// Perhaps look up the address from teh data base
// ...
// Update user contorl
obUC.strStreet = "456 ASPdotNET Avenue";
obUC.strCity = "Aspville, NT";
}
#region Web Form Designer generated code
...
#endregion
}
}
