www.gibmonks.com

Main Page

  Previous Section Next Section

6.1 User Controls

The simplest form of reuse in classic ASP is the include file. By adding the following directive:

<!-- #include file = "filename.inc" -->

classic ASP developers can place the contents of the specified file inline with the page in which the directive appeared. Unfortunately, this reuse technique is a bit crude and sometimes makes applications harder to debug.

While ASP.NET still supports include files, a better way to provide the same kinds of reuse is through a new feature called user controls. User controls can consist of any of the following:

  • HTML

  • Server-side script

  • Controls

all in a file with the .ascx file extension. When added to a Web Forms page, ASP.NET treats user controls as objects; these user controls can expose properties and methods like any other object. The rendered output of user controls can also be cached to improve application performance.

Example 6-1 shows a simple user control that provides navigational links to other examples in this chapter. The user control appears in each example to demonstrate how the use of a user control can provide a single point for modifying such frequently used elements as headers, footers, and navigation bars.

Example 6-1. Nav.ascx
<%@ Control Language="vb" %>
<table cellpadding="0" cellspacing="0">
   <tr>
      <td valign="top">
         <strong>Navigation Bar</strong><br/>
         <hr width='80%'>
         <a href="NavBarClient.aspx" 
            onmouseover="img1.src='node_rev.jpg';"
            onmouseout="img1.src='node.jpg';">
            <img border='0' align='absMiddle' alt='NavBar Client' 
               src='node.jpg' id='img1' name='img1'></a>
         <a href="NavBarClient.aspx" 
            onmouseover="img1.src='node_rev.jpg';" 
            onmouseout="img1.src='node.jpg';">NavBar Client</a>
         <hr width='80%'>
         <a href="UCClient.aspx" 
            onmouseover="img2.src='alt_node_rev.jpg';" 
            onmouseout="img2.src='alt_node.jpg';">
            <img border='0' align='absMiddle' alt='User Control Client'
               src='alt_node.jpg' id='img2' name='img2'></a>
         <a href="UCClient.aspx" 
            onmouseover="img2.src='alt_node_rev.jpg';" 
            onmouseout="img2.src='alt_node.jpg';">User Control Client</a>
         <hr width='80%'>
         <a href="BlogClient.aspx" 
            onmouseover="img3.src='node_rev.jpg';" 
            onmouseout="img3.src='node.jpg';">
            <img border='0' align='absMiddle' alt='Blog Client'
               src='node.jpg' id='img3' name='img3'></a>
         <a href="BlogClient.aspx" 
            onmouseover="img3.src='node_rev.jpg';" 
            onmouseout="img3.src='node.jpg';">Blog Client</a>
         <hr width='80%'>
         <a href="BlogAdd.aspx" 
            onmouseover="img3.src='alt_node_rev.jpg';" 
            onmouseout="img3.src='alt_node.jpg';">
            <img border='0' align='absMiddle' alt='Add New Blog' 
               src='alt_node.jpg' id='img3' name='img3'></a>
         <a href="BlogAdd.aspx" 
            onmouseover="img3.src='node_rev.jpg';" 
            onmouseout="img3.src='node.jpg';">Add New Blog</a>
         <hr width='80%'>
      </td>
   </tr>
</table>

With the exception of the @ Control directive, which is not strictly required, the code in Example 6-1 consists exclusively of HTML and client-side script (for performing a simple mouseover graphics switch). However, the user control could just as easily contain server controls and/or server-side script to perform more complicated tasks.

The @ Control directive performs essentially the same task as the @ Page directive, only for user controls. Chapter 3 lists the attributes of the @ Page and @ Control directives and the purpose of each.

The advantage of using a user control for this type of functionality is that it places all of our navigation logic in a single location. This placement makes it considerably easier to maintain the navigation links for a site. If you used ASP.NET's built-in server controls instead of raw HTML in your navigation user control, you could manipulate those server controls programmatically from the page on which the control is used. For example, you could hide the link to the page that's currently displayed or highlight it in some fashion.

The disadvantage of a user control is that it is not reusable across multiple sites ("site," here, refers to an IIS virtual directory defined as an application). It's also not usually a good idea to tightly couple user interface elements and data, as this control does, because doing so tends to reduce the reusability of a control. Later in this chapter, you'll see how to improve this user control by turning it into a custom server control.

User controls are made available to a page through the use of either the @ Register directive, which prepares a user control on a page declaratively (i.e., using a tag-based syntax like server controls), or, programmatically, using the LoadControl method of the TemplateControl class (from which both the Page class and the UserControl class derive).

Example 6-2 shows a page that uses the @ Register directive and a declarative tag to create the user control shown in Example 6-1. The @ Register directive in Example 6-2 tells ASP.NET to look for any <aspnetian:nav> tags with the runat="server" attribute, and when it finds one, create an instance of the user control and place its output where the tag is located. This allows us to place our control very precisely.

Example 6-2. UCClient.aspx
<%@ Page Language="vb" %>
<%@ Register TagPrefix="aspnetian" TagName="nav" Src="Nav.ascx" %>
<html>
<head>
</head>
<body>
   <table border="1" width="100%" cellpadding="20" cellspacing="0">
      <tr>
         <td align="center" width="150">
            <img src="aspnetian.jpg"/>
         </td>
         <td align="center">
            <h1>User Control Client Page<h1>
         </td>
      </tr>
      <tr>
         <td width="150">
            <aspnetian:nav runat="server"/>
         </td>
         <td>
            This is where page content might be placed
            <br/><br/><br/><br/><br/><br/><br/><br/><br/>
         </td>
      </tr>
   </table>
</body>
</html>

You can instead create the control dynamically using the LoadControl method and add the control to either the Controls collection of the page, or, better yet, to the Controls collection of a PlaceHolder control. The latter allows you to control the location of the user control based on the location of the placeholder. You might choose to use this technique if you know where you want the control to reside on the page, but don't necessarily want the control loaded and displayed on every request. This technique is shown in Example 6-3.

Example 6-3. UCClient_Prog.aspx
<%@ Page Language="vb" %>
<html>
<head>
   <script runat="server">
      Sub Page_Init( )
         PH.Controls.Add(LoadControl("Nav.ascx"))
      End Sub
   </script>
</head>
<body>
   <table border="1" width="100%" cellpadding="20" cellspacing="0">
      <tr>
         <td align="center" width="150">
            <img src="aspnetian.jpg"/>
         </td>
         <td align="center">
            <h1>User Control Client Page<h1>
         </td>
      </tr>
      <tr>
         <td width="150">
            <asp:placeholder id="PH" runat="server"/>
         </td>
         <td>
            This is where page content might be placed
            <br/><br/><br/><br/><br/><br/><br/><br/><br/>
         </td>
      </tr>
   </table>
</body>
</html>

If you want to work with the control after loading it using LoadControl, you need to cast the control to the correct type using the CType function in Visual Basic .NET or by preceding the control with (typename) in C#. Note that this requires that the user control be defined in a class that inherits from UserControl, so this technique would not work with the user control in Example 6-1.

      Previous Section Next Section