One common problem that many Web site developers encounter when building an online store concerns the variety of products that the store sells. For example, a store might want to sell a wide range of products, including ping-pong balls, cameras , and CDs. The problem is how to create a single product page that can be used to sell anything. A page layout that works well with one product might not work well at all with another product. For example, a common problem is that one product will have pictures and another product won't. One way around this problem is not to try to create a single page for all the products that your Web site might sell. That's the approach taken in the case of the ASP.NET Unleashed Sample Store. Every product sold through the ASP.NET Unleashed Sample Store is associated with a product template. Products are associated with individual templates through the Template database column in the Products database table. When you install the ASP.NET Unleashed Sample Store, by default, the same template is associated with every product. This template is named the default template and can be found in the ProductTemplates subdirectory. However, it's easy to add a new template. To create a special template for all the products in the Seafood category, for example, you first make a new template file. A file with the proper format is contained in Listing 31.6. Listing 31.6 Seafood.ascx<%@ Inherits="StoreComponents.ProductTemplate" %> <h2>The Custom Seafood Template<h2> <font color="red"><%=Product( "QuantityPerUnit" )%></font> <hr> <font size="8" color="DarkRed"><%= ProductName %></font> <p> <font size="5"><%= UnitPrice.ToString( "c" ) %></font> The C# version of this code can be found on the CD-ROM. Notice that the product template is a user control file (an .ascx file). Also, notice that it displays the value of a database column that the default product template doesn't display. This template displays the value of the QuantityPerUnit column. Now that you have a new template, you need to associate it with all the Seafood products. You can do this by executing the following SQL statement from SQL Query Analyzer: Update Products Set Template='Seafood' Where CategoryID=8 This SQL Update statement changes the value of the Template column to Seafood so that your new template will be displayed. If you browse to a Seafood product in the ASP.NET Unleashed Sample Store, the product should be displayed with your new template (see Figure 31.3). Figure 31.3. The Seafood template.
Using dynamically loaded controls in this way provides a great deal of flexibility. You can use user controls to free yourself from being locked down to a particular user interface. In the next two sections, you examine how these templates are implemented. Using the LoadControl MethodYou can display different templates for the different products in your store because of the way the Product.aspx page was written. The Product.aspx page was written to take advantage of dynamically loaded user controls. NOTE For an example of an application that makes even more extensive use of dynamically loaded user controls than your sample store, see the IBuySpy Portal application at www.ibuyspy.com. The code for the Product.aspx page is contained in Listing 31.7. Listing 31.7 Product.aspx [View full width] <!-- #include virtual="/aspnetstore/includes/header.aspx" --> <Script runat="Server"> Sub Page_Load Dim intProductID As Integer Dim strProductTemplate As String Dim objProductTemplate As ProductTemplate intProductID = Context.Items( "ProductID" ) strProductTemplate = CachedData.GetProductTemplate( intProductID ) strProductTemplate = String.Format( "/aspnetstore/ProductTemplates/{0}.ascx", strProductTemplate ) objProductTemplate = LoadControl( strProductTemplate ) plhProductTemplate.Controls.Add( objProductTemplate ) End Sub </Script> <html> <head> <link href="/aspnetstore/Styles/Store.css" type="text/css" rel="stylesheet" /> <title><%=Context.Items( "ProductName" )%></title> </head> <body bgcolor="lightblue"> <a href="Default.aspx"><img src="banner.gif" border="1"></a> <form runat="Server"> <myControls:Tabs Runat="Server" /> <table width="800" height="100%" cellpadding="10" cellspacing="0" border="0"> <tr> <td valign="top" bgcolor="lightyellow"> <myControls:ShoppingCart Runat="Server" /> </td> <td width="100%" valign="top" bgcolor="white"> <asp:PlaceHolder id="plhProductTemplate" Runat="Server" /> </td> </tr> </table> </form> <!-- #include virtual="/aspnetstore/includes/footer.aspx" --> The C# version of this code can be found on the CD-ROM. Within the Page_Load subroutine in Listing 31.7, you dynamically load a user control. The user control is dynamically loaded with the LoadControl method of the Page class. The LoadControl method takes a single parameter: the path of the user control that you want to load. Next, the dynamically loaded control is added to the controls collection of a PlaceHolder Web control. The PlaceHolder control is located in the body of the page. The Code-Behind Product TemplateYou have to use one more trick to get your dynamically loaded product template to work. You might be wondering how you have access to all the columns from the Products database table in your product templates. The answer is that all the product templates derive from a single code-behind product template. The code-behind product template is declared in the StoreComponents assembly. The source code for this class is contained in Listing 31.8. Listing 31.8 ProductTemplate.vbPublic Class ProductTemplate : inherits UserControl Public ReadOnly Property ProductID As Integer Get Return Context.Items( "ProductID" ) End Get End Property Public ReadOnly Property ProductName As String Get Return Context.Items( "ProductName" ) End Get End Property Public ReadOnly Property UnitPrice As Decimal Get Return Context.Items( "UnitPrice" ) End Get End Property Public ReadOnly Property Product As DataRowView Get Return Context.Items( "ProductInfo" ) End Get End Property End Class The C# version of this code can be found on the CD-ROM. The code-behind product template contains four properties that represent the values of four database columns: ProductID , ProductName , UnitPrice. The template contains one additional property named Product . The Product column contains all the columns from the underlying database row that represents the product. You can use the Product property to display the value of any database column. For example, this property was used in the Seafood product template to display the value of the QuantityPerUnit database column like this: <font color="red"><%=Product( "QuantityPerUnit" )%></font> |