User controls can be created in a method similar to the way you create your typical ASP.NET web form pages. The primary difference between ASP.NET web form pages and User controls is that User controls do not include <html><body> and <form runat="server"> tags within them. These tags would already be included in your ASP.NET web form page.
ASP.NET pages can contain only one <form runat="server"> tag per page. You can include as many standard <form> tags as you'd like, but there can be only one "web form" per ASP.NET page.
Let's start out with a simple example of a form box that asks what the password is and go from there. The following are the User control pages. Notice that a User control must have a file extension of .ascx.
<script language="vb" runat=server> Sub Btn_Click(Sender as Object, E as EventArgs) if thepassword.Text.ToLower = "holy grail" then OurLabel.Text = "You have chosen wisely!" else OurLabel.Text = "You have chosen poorly!" end if End Sub </script> <table width="200" border="0" cellspacing="0" cellpadding="5"> <tr> <td><div align="center"> <asp:Textbox TextBoxMode="password" runat="server"/> </div></td> </tr> <tr> <td> <div align="center"> <asp:Button text="What's the password?" OnClick="Btn_Click" runat="server"/> </div> </td> </tr> <tr> <td><div align="center"> <asp:Label runat="server"/> </div></td> </tr> </table>
<script language="c#" runat=server> void Btn_Click(object Source, System.EventArgs s){ if (thepassword.Text.ToLower() == "holy grail"){ OurLabel.Text = "You have chosen wisely!"; }else{ OurLabel.Text = "You have chosen poorly!"; } } </script> <table width="200" border="0" cellspacing="0" cellpadding="5"> <tr> <td><div align="center"> <asp:Textbox TextBoxMode="password" runat="server"/> </div></td> </tr> <tr> <td> <div align="center"> <asp:Button text="What's the password?" OnClick="Btn_Click" runat="server"/> </div> </td> </tr> <tr> <td><div align="center"> <asp:Label runat="server"/> </div></td> </tr> </table>
As you can see, this page is really no different than a typical ASP.NET page with the exception of the tags mentioned earlier. We have some logical code and UI code that have some interplay when our button is clicked.
The following shows you the code of the ASP.NET web form page. Notice how the @Register directive that we explored in Chapter 5 is used to set up a custom tag name and tag prefix for the User control, and how it's plopped in wherever we want the User control inserted by referencing the custom tag created with this directive.
<%@ page language="vb" EnableViewState="false" runat="server"%> <%@Register TagPrefix="Peter" Tagname="PasswordTest" src="/books/1/582/1/html/2/uc_simple_vb.ascx"%> <script runat="server"> Sub Page_Load() OurTitle.Text = "<u><b>What is your Quest?<br>I seek the . . . </b></u>" End Sub </script> <html> <title>User Controls - Simple</title> <body> <form runat="server"> <table width="200" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <div align="center"> <asp:label runat="server"/> </div> </td> <tr> <td> <Peter:PasswordTest runat="server"/> </td> </tr> </table> </form> </body> </html>
<%@ page language="c#" EnableViewState="false" runat="server"%> <%@Register TagPrefix="Peter" Tagname="PasswordTest" src="/books/1/582/1/html/2/uc_simple_cs.ascx"%> <script runat="server"> void Page_Load(){ OurTitle.Text = "<u><b>What is your Quest?<br>I seek the . . . </b></u>"; } </script> <html> <title>User Controls - Simple</title> <body> <form runat="server"> <table width="200" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <div align="center"> <asp:label runat="server"/> </div> </td> <tr> <td> <Peter:PasswordTest runat="server"/> </td> </tr> </table> </form> </body> </html>
In Figure 5.1, you can see both what was in the .aspx page and also the content and functionality encapsulated inside the User control.
If you look at the rendered HTML you'll see that it's inserted the User control into the page seamlessly.
<html> <title>User Controls - Simple</title> <body> <form name="passwordform" method="post" action="uc_simple_vb.aspx" > <input type="hidden" name="__VIEWSTATE" value="dDwtMzQyOTAzMjY2Ozs+sDEoFA1dlzcJtRzMTXy4Q/ BrZJQ=" /><table width="200" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <div align="center"> <span ><u><b>What is your Quest?<br>I seek the . . . </b></u></span> </div> </td> <tr> <td> <table width="200" border="0" cellspacing="0" cellpadding="5"> <tr> <td><div align="center"> <input name="OurPassword:thepassword" type="text" value="holy grail" TextBoxMode="password" /> </div></td> </tr> <tr> <td> <div align="center"> <input type="submit" name="OurPassword:Password_Btn" value="What's the password?" /> </div> </td> </tr> <tr> <td><div align="center"> <span >You have chosen wisely!</span> </div></td> </tr> </table> </td> </tr> </table> </form> </body> </html>
Sometimes (actually most times) it can be easier to create a User control by actually creating it first as a standard ASP.NET web form page and then converting it to a User control afterward. This gives you the flexibility to test it as a self-contained unit and debug it totally before you try including it in other pages where it can muddy the water and become difficult to debug. To convert an ASP.NET web form page into a User control, simply remove all the <html></html>, <body></body>, and <form runat="server"></form> tags from the page.
Understanding that User controls are strikingly similar to standard ASP.NET web form pages, and that one of ASP.NET's goals is to help separate code from content, it only makes sense that you can utilize code behind techniques in User controls just like you do in ASP.NET pages.
Let's take the previous example and convert it to a user control that utilizes code behind. First, look at the code behind page.
Imports System Imports System.Web.UI Imports System.Web.UI.WebControls public class OurUCCodeBehind Inherits UserControl public thepassword as TextBox public OurLabel as Label Sub Btn_Click(Sender as Object, E as EventArgs) if thepassword.Text.ToLower = "holy grail" then OurLabel.Text = "You have chosen wisely!" else OurLabel.Text = "You have chosen poorly!" end if End Sub End Class
using System; using System.Web.UI; using System.Web.UI.WebControls; public class OurUCCodeBehind:UserControl{ public TextBox thepassword; public Label OurLabel; public void Btn_Click(object Source, System.EventArgs s){ if (thepassword.Text.ToLower() == "holy grail"){ OurLabel.Text = "You have chosen wisely!"; }else{ OurLabel.Text = "You have chosen poorly!"; } } }
Notice again just like in the discussion about code behind that you must import the proper namespaces into your code behind page, as well as replicate instances of all needed objects as well. Now look at the User control.
<%@control inherits="OurUCCodeBehind" src="/books/1/582/1/html/2/uc_codebehind.vb" %> <table width="200" border="0" cellspacing="0" cellpadding="5"> <tr> <td><div align="center"> <asp:Textbox TextBoxMode="password" runat="server"/> </div></td> </tr> <tr> <td> <div align="center"> <asp:Button text="What's the password?" OnClick="Btn_Click" runat="server"/> </div> </td> </tr> <tr> <td><div align="center"> <asp:Label runat="server"/> </div></td> </tr> </table>
<%@ control inherits = "OurUCCodeBehind" src = "uc_codebehind.cs" %> <table width="200" border="0" cellspacing="0" cellpadding="5"> <tr> <td><div align="center"> <asp:Textbox TextBoxMode="password" runat="server"/> </div></td> </tr> <tr> <td> <div align="center"> <asp:Button text="What's the password?" OnClick="Btn_Click" runat="server"/> </div> </td> </tr> <tr> <td><div align="center"> <asp:Label runat="server"/> </div></td> </tr> </table>
As you can see, the class name created in the code behind page is inherited into the User control the same way a code behind class is inherited into a standard ASP.NET web form page. Instead of this inheritance and source attribute being set in the @Page directive, it is set in the @Control directive. This is the User control's version of this directive (as discussed in Chapter 4). Just as you can have only one @Page directive on your ASP.NET page, you can have only one @Control directive on your User control pages.
Again, you are faced with the tradeoff that this layer of code separation requires: specifically, importing namespaces and initialization of objects in the code behind page. Again this comes down to personal or development team choice.
Top |