Programming
Article

Constructing ASP.NET Web Pages

By Cristian Darie & Wyatt Barnett

If you’ve ever built a model from Lego bricks, you’re well prepared to start building real ASP.NET web pages. ASP.NET offers features that allow web developers to build parts of web pages independently, then put them together later to form complete pages.

The content we’re creating through our work with ASP.NET is almost never static. At design time, we tend to think in terms of templates that contain placeholders for the content that will be generated dynamically at runtime. And to fill those placeholders, we can either use one of the many controls ASP.NET provides, or build our own.

In this chapter of the fabulous new edition of Build Your Own ASP.NET 3.5 Web Site Using C# & VB, we’ll discuss many of the objects and techniques that give life and color to ASP.NET web pages, including:

  • web forms
  • HTML server controls
  • web server controls
  • web user controls
  • master pages
  • handling page navigation
  • styling pages and controls with CSS

If the list looks intimidating, don’t worry – all of this is far easier to understand than it might first appear. And to help you along, you can now visit the book’s web page to download the first four chapters for free! In fact, it’s highly recommended that you do have the downloaded pdf handy if you want to take part in the practical side of this chapter, as we work through some exercises that necessitate the creation of folders and files as described in Chapter 1.

Web Forms

As you know, there’s always new terminology to master when you’re learning new technologies. The term used to describe an ASP.NET web page is web form, and this is the central object in ASP.NET development. At first glance, web forms look much like HTML pages, but in addition to static HTML content, they contain ASP.NET-specific elements, and code that executes on the server side.

Every web form includes a <form runat="server"> tag, which contains the ASP.NET-specific elements that make up the page. Multiple forms aren’t supported. The basic structure of a web form is shown here:

<%@ Page Language="language" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
   ... code block...
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
 <title>Page Title</title>
</head>
<body>
 <form id="form1" runat="server">
   ... user interface elements...
 </form>
</body>
</html>

To access and manipulate a web form programmatically, we use the System.Web.UI.Page class. We must mention the class explicitly in the code-behind file. In situations in which we’re not using code-behind files (that is, when we’re writing all the code inside the .aspx file instead), the Page class is still used – we just don’t see it.

We can use a range of user interface elements inside the form – including typical static HTML code – but we can also use elements whose values or properties can be generated or manipulated on the server either when the page first loads, or when the form is submitted. These elements – which, in ASP.NET parlance, are called controls – allow us to reuse common functionality, such as the page header, a calendar, a shopping cart summary, or a “Today’s Quote” box, for example, across multiple web forms. There are several types of controls in ASP.NET:

  • HTML server controls
  • web server controls
  • web user controls
  • master pages

There are significant technical differences between these types of controls, but what makes them similar is the ease with which we can integrate and reuse them in our web sites. Let’s take a look at them one by one.

HTML Server Controls

HTML server controls are outwardly identical to plain old HTML tags, but include a runat="server" attribute. This gives the ASP.NET runtime control over the HTML server controls, allowing us to access them programmatically. For example, if we have an <a> tag in a page and we want to be able to change the address to which it links dynamically, using VB or C# code, we use the runat="server" attribute.

A server-side HTML server control exists for each of HTML’s most common elements. Creating HTML server controls is easy: we simply stick a runat="server" attribute on the end of a normal HTML tag to create the HTML control version of that tag. The complete list of current HTML control classes and their associated tags is given in Table 1.

Table 1. HTML control classes

Class Associated Tags
HtmlAnchor <a runat="server">

HtmlButton <button runat="server">

HtmlForm <form runat="server">

HtmlImage <img runat="server">

HtmlInputButton <input type="submit" runat="server">

HtmlInputCheckBox <input type="reset" runat="server">

<input type="button" runat="server">
<input type="checkbox" runat="server">
HtmlInputFile <input type="file" runat="server">
HtmlInputHidden <input type="hidden" runat="server">
HtmlInputImage <input type="image" runat="server">
HtmlInputRadioButton <input type="radio" runat="server">
HtmlInputText <input type="text" runat="server">
HtmlSelect <input type="password" runat="server">
<select runat="server">
HtmlTable <table runat="server">
HtmlTableRow <tr runat="server">
HtmlTableCell <td runat="server">
HtmlTextArea <th runat="server">
<textarea runat="server">

HtmlGenericControl

<span runat="server">

<div runat="server">

All other HTML tags

All the HTML server control classes are contained within the System.Web.UI.HtmlControls namespace. As they’re processed on the server side by the ASP.NET runtime, we can access their properties through code elsewhere in the page. If you’re familiar with JavaScript, HTML, and CSS, you’ll know that manipulating text within HTML tags, or even manipulating inline styles within an HTML tag, can be cumbersome and error-prone. HTML server controls aim to solve these problems by allowing you to manipulate the page easily with your choice of .NET language – for instance, using VB or C#.

Using the HTML Server Controls

Nothing explains the theory better than a simple, working example. Let’s create a simple survey form that uses the following HTML server controls:

  • HtmlForm
  • HtmlButton
  • HtmlInputText
  • HtmlSelect

We’ll begin by creating a new file named Survey.aspx. Create the file in the LearningASPVB or LearningASPCS folder that we cover in Chapter 1 of the downloadable pdf of this book. For the purpose of the exercises in this chapter we won’t be using a code-behind file, so don’t check the Place code in a separate file checkbox when you create the form.

Update the automatically generated file with the following code to create the visual interface for the survey:

Visual Basic LearningASPVBSurvey_01.aspx (excerpt)
<%@ Page Language="VB" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
 <head runat="server">
   <title>Using ASP.NET HTML Server Controls</title>
 </head>
 <body>
   <form id="form1" runat="server">
   <div>
     <h1>Take the Survey!</h1>
     <!-- Display user name -->
     <p>
       Name:<br />
       <input type="text" id="name" runat="server" />
     </p>
     <!-- Display email -->
     <p>
       Email:<br />
       <input type="text" id="email" runat="server" />
     </p>
     <!-- Display technology options -->
     <p>
       Which server technologies do you use?<br />
       <select id="serverModel" runat="server" multiple="true">
         <option>ASP.NET</option>
         <option>PHP</option>
         <option>JSP</option>
         <option>CGI</option>
         <option>ColdFusion</option>
       </select>
     </p>
     <!-- Display .NET preference options -->
     <p>
       Do you like .NET so far?<br />
       <select id="likeDotNet" runat="server">
         <option>Yes</option>
         <option>No</option>
       </select>
     </p>
     <!-- Display confirmation button -->
     <p>
       <button id="confirmButton" OnServerClick="Click"
           runat="server">Confirm</button>
     </p>
     <!-- Confirmation label -->
     <p>
       <asp:Label id="feedbackLabel" runat="server" />
     </p>

   </div>
   </form>
 </body>
</html>

The C# version is identical except for the first line – the page declaration:

C# LearningASPCSSurvey_01.aspx (excerpt)
<%@ Page Language="C#" %>
...

From what we’ve already seen of HTML controls, you should have a good idea of the classes we’ll be working with in this page. All we’ve done is place some HtmlInputTextcontrols, an HtmlButtoncontrol, and an HtmlSelect control inside the obligatory HtmlForm control. We’ve also added a Label control, which we’ll use to give feedback to the user.

TIP: HTML Server Controls in Action
Remember, HTML server controls are essentially HTML tags with the runat="server" attribute. In most cases, you’ll also need to assign them IDs, which will enable you to use the controls in your code.

NOTE: Validation Warnings
You may notice that Visual Web Developer will display a validation warning about the multiple="true" attribute value on the selectelement. In XHTML 1.0, the select element only supports multiple="multiple" and the IDE dutifully reports the problem. However, since this is a server control – it has a runat="server" attribute – you must specify multiple="true", otherwise the page will not compile and execute.

When you eventually test this page, you’ll be happy to note that ASP.NET will change the attribute value to multiple="multiple" when the HTML is generated and the page is displayed.

When it’s complete, and you view it in Visual Web Developer’s Design mode, the Survey.aspx web form will resemble Figure 1. Note that you can’t execute the form yet, because it’s missing the button’s Clickevent handler that we’ve specified using the OnServerClick attribute on the HtmlButton control.

A simple form that uses HTML server controls

When a user clicks on the Confirm button, we’ll display the submitted responses in the browser. In a real application, we’d probably be more likely to save this information to a database, and perhaps show the results as a chart. Whatever the case, the code for the Click event handler method below shows how we’d access the properties of the HTML controls:

Visual Basic LearningASPVBSurvey_02.aspx (excerpt)
<script runat="server">  
Sub Click(ByVal s As Object, ByVal e As EventArgs)  
   Dim i As Integer  
   feedbackLabel.Text = "Your name is: " & name.Value & "<br />"  
   feedbackLabel.Text += "Your email is: " & email.Value & _  
       "<br />"  
   feedbackLabel.Text += "You like to work with:<br />"  
   For i = 0 To serverModel.Items.Count - 1  
     If serverModel.Items(i).Selected Then  
       feedbackLabel.Text += " - " & _  
           serverModel.Items(i).Text & "<br />"  
     End If  
   Next i  
   feedbackLabel.Text += "You like .NET: " & likeDotNet.Value  
 End Sub
 
</script>

C# LearningASPCSSurvey_02.aspx (excerpt)
<script runat="server">  
void Click(Object s, EventArgs e)  
 {  
   feedbackLabel.Text = "Your name is: " + name.Value + "<br />";  
   feedbackLabel.Text += "Your email is: " + email.Value +  
       "<br />";  
   feedbackLabel.Text += "You like to work with:<br />";  
   for (int i = 0; i <= serverModel.Items.Count - 1; i++)  
   {  
     if (serverModel.Items[i].Selected)  
     {  
       feedbackLabel.Text += " - " + serverModel.Items[i].Text +  
           "<br />";  
     }  
   }  
   feedbackLabel.Text += "You like .NET: " + likeDotNet.Value;  
 }
 
</script>

As with the examples we’ve seen in previous chapters, we start by placing our VB and C# code inside a server-side script block within the <script> part of the page. Next, we create a new Click event handler that takes the two usual parameters. Finally, we use the Label control to display the user’s responses within the page.

Once you’ve written the code, save your work and test the results in your browser. Enter some information and click the button. To select multiple options in the serverModel option box, hold down Ctrl as you click on your preferences. The information you enter should appear at the bottom of the page when the Confirm button is clicked, as shown in Figure 2.

Viewing the survey results

In conclusion, working with HTML server controls is really simple. All you need to do is assign each control an ID, and add the runat="server" attribute. Then, you can simply access and manipulate the controls using VB or C# code on the server side.

Web Server Controls

Web server controls can be seen as advanced versions of HTML server controls. Web server controls are those that generate content for you – you’re no longer in control of the HTML being used. While having good knowledge of HTML is useful, it’s not a necessity for those working with web server controls.

Let’s look at an example. We can use the Label web server control to place simple text inside a web form. To change the Label‘s text from within our C# or VB code, we simply set its Text property like so:

Visual Basic
myLabel.Text = "Mickey Mouse"

Similarly, to add a text box to our form, we use the TextBox web server control. Again, we can read or set its text using the Text property:

C#
username = usernameTextBox.Text;

Though we’re applying the TextBox control, ASP.NET still uses an input element behind the scenes; however, we no longer have to worry about this detail. With web server controls, you no longer need to worry about translating the needs of your application into elements you can define in HTML – you can let the ASP.NET framework do the worrying for you.

Unlike HTML server controls, web server controls don’t have a direct, one-to-one correspondence with the HTML elements they generate. For example, we can use either of two web server controls – the DropDownList control, or the ListBox control – to generate a select element.

Web server controls follow the same basic pattern as HTML tags, but the tag name is preceded by asp:, and is capitalized using Pascal Casing. Pascal Casing is a form that capitalizes the first character of each word (such as TextBox). The object IDs are usually named using Camel Casing, where the first letter of each word except the first is capitalized (e.g. usernameTextBox).

Consider the following HTML input element, which creates an input text box:

<input type="text" name="usernameTextBox" size="30" />

The equivalent web server control is the TextBox control, and it looks like this:

<asp:TextBox id="usernameTextBox" runat="server" Columns="30"></asp:TextBox>

Remember that, unlike any normal HTML that you might use in your web forms, web server controls are first processed by the ASP.NET engine, where they’re transformed to HTML. A side effect of this approach is that you must be very careful to always include closing tags (the </asp:TextBox> part above). The HTML parsers of most web browsers are forgiving about badly formatted HTML code, but ASP.NET is not. Remember that you can use the shorthand syntax (/>) if nothing appears between your web server control’s opening and closing tags. As such, you could also write this TextBox like so:

<asp:TextBox id="usernameTextBox" runat="server" Columns="30" />

To sum up, the key points to remember when you’re working with web server controls are:

  • Web server controls must be placed within a <form runat="server"> tag to function properly.
  • Web server controls require the runat="server" attribute to function properly.
  • We include web server controls in a form using the asp: prefix.

There are more web server controls than HTML controls. Some offer advanced features that simply aren’t available using HTML alone, and some generate quite complex HTML code for you. We’ll meet many web server controls as we work through this and future chapters in the book. For more information on web server controls, including the properties, methods, and events for each, have a look at Appendix A of this book.

Standard Web Server Controls

The standard set of web server controls that comes with ASP.NET mirrors the HTML server controls in many ways. However, web server controls offer some new refinements and enhancements, such as support for events and view state, a more consistent set of properties and methods, and more built-in functionality. In this section, we’ll take a look as some of the controls you’re most likely to use in your day-to-day work.

Remember to use the .NET Framework SDK Documentation whenever you need more details about any of the framework’s classes (or controls). You can access the documentation from the Help > Index menu item in Visual Web Developer. To find a class, simply search for the class’s name. If there are many classes with a given name in different namespaces, you’ll be able to choose the one you want from the Index Results window. For example, you’ll find that there are two classes named Label, located in the System.Web.UI.WebControls and System.Windows.Forms namespaces, as Figure 3 illustrates. You’ll most likely be interested in the version of the class situated in the WebControls namespace.

Documentation for the Label control

Label

The easiest way to display static text on your page is simply to add the text to the body of the page without enclosing it in a tag. However, if you want to modify the text displayed on a page using ASP.NET code, you can display your text within a Label control. Here’s a typical example:

<asp:Label id="messageLabel" Text="" runat="server" />

The following code sets the Text property of the Label control to display the text “Hello World”:

Visual Basic
Public Sub Page_Load()  
 messageLabel.Text = "Hello World"  
End Sub

C#
public void Page_Load()  
{  
 messageLabel.Text = "Hello World";    
}

Reading this Page_Load handler code, we can see that when the page first loads, the Text property of the Label control with the id of message will be set to “Hello World.”

Literal

This is perhaps the simplest control in ASP.NET. If you set Literal‘s Text property, it will simply insert that text into the output HTML code without altering it. Unlike Label, which has similar functionality, Literal doesn’t wrap the text in <span> tags that would allow the setting of style information.

TextBox

The TextBox control is used to create a box in which the user can type or read standard text. You can use the TextMode property to set this control to display text in a single line, across multiple lines, or to hide the text being entered (for instance, in HTML password fields). The following code shows how we might use it in a simple login page:

<p>    
 Username: <asp:TextBox id="userTextBox" TextMode="SingleLine"  
   Columns="30" runat="server" />  
</p>  
<p>    
 Password: <asp:TextBox id="passwordTextBox"    
     TextMode="Password" Columns="30" runat="server" />  
</p>  
<p>    
 Comments: <asp:TextBox id="commentsTextBox"  
     TextMode="MultiLine" Columns="30" Rows="10"  
     runat="server" />  
</p>

In each of the instances above, the TextMode attribute dictates the kind of text box that’s to be rendered.

HiddenField
HiddenField is a simple control that renders an input element whose type attribute is set to hidden. We can set its only important property, Value. 

Button

By default, the Button control renders an input element whose type attribute is set to submit. When a button is clicked, the form containing the button is submitted to the server for processing, and both the Click and Command events are raised.

The following markup displays a Button control and a Label:

<asp:Button id="submitButton" Text="Submit" runat="server"   
   OnClick="WriteText" />  
<asp:Label id="messageLabel" runat="server" />

Notice the OnClick attribute on the control. When the button is clicked, the Click event is raised, and the WriteText subroutine is called. The WriteText subroutine will contain the code that performs the intended function for this button, such as displaying a message to the user:

Visual Basic
Public Sub WriteText(s As Object, e As EventArgs)  
 messageLabel.Text = "Hello World"  
End Sub

C#
public void WriteText(Object s, EventArgs e)  
{  
   messageLabel.Text = "Hello World";  
}

It’s important to realize that events are associated with most web server controls, and the basic techniques involved in using them, are the same events and techniques we used with the Click event of the Button control. All controls implement a standard set of events because they all inherit from the WebControl base class.

ImageButton

An ImageButton control is similar to a Button control, but it uses an image that we supply in place of the typical system button graphic. Take a look at this example:

<asp:ImageButton id="myImgButton" ImageUrl="myButton.gif"   
   runat="server" OnClick="WriteText" />  
<asp:Label id="messageLabel" runat="server" />

The Click event of the ImageButton receives the coordinates of the point at which the image was clicked:

Visual Basic
Public Sub WriteText(s As Object, e As ImageClickEventArgs)  
 messageLabel.Text = "Coordinate: " & e.X & "," & e.Y  
End Sub

C#
public void WriteText(Object s, ImageClickEventArgs e)  
{  
 messageLabel.Text = "Coordinate: " + e.X + "," + e.Y;  
}

LinkButton

A LinkButton control renders a hyperlink that fires the Click event when it’s clicked. From the point of view of ASP.NET code, LinkButtons can be treated in much the same way as buttons, hence the name. Here’s LinkButton in action:

<asp:LinkButton id="myLinkButon" Text="Click Here"    
   runat="server" />

HyperLink

The HyperLink control creates on your page a hyperlink that links to the URL in the NavigateUrl property. Unlike the LinkButton control, which offers features such as Click events and validation, HyperLinks are meant to be used to navigate from one page to the next:

<asp:HyperLink id="myLink" NavigateUrl="http://www.sitepoint.com/"   
   ImageUrl="splogo.gif" runat="server">SitePoint</asp:HyperLink>

If it’s specified, the ImageUrl attribute causes the control to display the specified image, in which case the text is demoted to acting as the image’s alternate text.

CheckBox

You can use a CheckBox control to represent a choice that can have only two possible states – checked or unchecked:

<asp:CheckBox id="questionCheck" Text="Yep, ASP.NET is cool!"   
   Checked="True" runat="server" />

The main event associated with a CheckBox is the CheckChanged event, which can be handled with the OnCheckChanged attribute. The Checked property is True if the checkbox is checked, and False otherwise.

RadioButton

A RadioButton is a lot like a CheckBox, except that RadioButtons can be grouped to represent a set of options from which only one can be selected. Radio buttons are grouped together using the GroupName property, like so:

<asp:RadioButton id="sanDiego" GroupName="City" Text="San Diego"   
   runat="server" /><br /><asp:RadioButton id="boston" GroupName="City" Text="Boston"  
   runat="server" /><br /><asp:RadioButton id="phoenix" GroupName="City" Text="Phoenix"  
   runat="server" /><br /><asp:RadioButton id="seattle" GroupName="City" Text="Seattle"  
   runat="server" />

Like the CheckBox control, the main event associated with RadioButtons is the CheckChanged event, which can be handled with the OnCheckChanged attribute. The other control we can use to display radio buttons is RadioButtonList, which we’ll also meet in this chapter.

Image

An Image control creates an image that can be accessed dynamically from code; it equates to the <img> tag in HTML. Here’s an example:

<asp:Image id="myImage" ImageUrl="mygif.gif" runat="server"   
   AlternateText="description" />

ImageMap

The ImageMap control generates HTML to display images that have certain clickable regions called hot spots. Each hot spot reacts in a specific way when it’s clicked by the user.

These areas can be defined using three controls, which generate hot spots of different shapes: CircleHotSpot, RectangleHotSpot, and PolygonHotSpot. Here’s an example that defines an image map with two circular hot spots:

<asp:ImageMap ID="myImageMap" runat="server" ImageUrl="image.jpg">   <asp:CircleHotSpot AlternateText="Button1"    
     Radius="20" X="50" Y="50" />    
  <asp:CircleHotSpot AlternateText="Button2"    
     Radius="20" X="100" Y="50" />    
</asp:ImageMap>


Table 2. Possible values of HotSpotMode

HotSpotMode value Behavior when hot spot is clicked
Inactive none
Navigate The user is navigated to the specified URL.
NotSet When this value is set for a HotSpot, the behavior is inherited from the parent ImageMap; if the parent ImageMap doesn't specify a defaultvalue, Navigate is set.
When it's set for an ImageMap, this value is effectively equivalent to Navigate.
PostBack The hot spot raises the Clickevent that can be handled on the server side to respond to the user action.

To configure the action that results when a hot spot is clicked by the user, we set the HotSpotMode property of the ImageMap control, or the HotSpotMode property of the individual hot spot objects, or both, using the values shown in Table 2. If the HotSpotMode property is set for the ImageMap control as well as for an individual hot spot, the latter property will override that set for the more general ImageMap control.

The Microsoft .NET Framework SDK Documentation for the ImageMap class and HotSpotMode enumeration contains detailed examples of the usage of these values.

PlaceHolder

The PlaceHolder control lets us add elements at a particular place on a page at any time, dynamically, through our code. Here's what it looks like:

<asp:PlaceHolder id="myPlaceHolder" runat="server" />

The following code dynamically adds a new HtmlButton control within the placeholder:

Visual Basic
Public Sub Page_Load()    
 Dim myButton As HtmlButton = New HtmlButton()    
 myButton.InnerText = "My New Button"    
 myPlaceHolder.Controls.Add(myButton)    
End Sub

C#
public void Page_Load()    
{    
 HtmlButton myButton = new HtmlButton();    
 myButton.InnerText = "My New Button";    
 myPlaceHolder.Controls.Add(myButton);    
}

Panel

The Panel control functions similarly to the div element in HTML, in that it allows the set of items that resides within the tag to be manipulated as a group. For instance, the Panel could be made visible or hidden by a Button‘s Click event:

<asp:Panel id="myPanel" runat="server">     
 <p>Username: <asp:TextBox id="usernameTextBox" Columns="30"    
     runat="server" /></p>    
<p>Password: <asp:TextBox id="passwordTextBox"    
     TextMode="Password" Columns="30" runat="server" /></p>    
</asp:Panel>    
<asp:Button id="hideButton" Text="Hide Panel" OnClick="HidePanel"    
   runat="server" />

The code above places two TextBox controls within a Panel control. The Button control is outside of the panel. The HidePanel subroutine would then control the Panel‘s visibility by setting its Visible property to False:

Visual Basic
Public Sub HidePanel(s As Object, e As EventArgs)    
 myPanel.Visible = False    
End Sub


C#
public void HidePanel(Object s, EventArgs e)    
{    
 myPanel.Visible = false;    
}

In this case, when the user clicks the button, the Click event is raised and the HidePanel subroutine is called, which sets the Visible property of the Panel control to False.

List Controls

Here, we’ll meet the ASP.NET controls that display simple lists of elements: ListBox, DropDownList, CheckBoxList, RadioButtonList, and BulletedList.

DropDownList

A DropDownList control is similar to the HTML select element. The DropDownList control allows you to select one item from a list using a drop-down menu. Here’s an example of the control’s code:

<asp:DropDownList id="ddlFavColor" runat="server">     
 <asp:ListItem Text="Red" value="red" />    
 <asp:ListItem Text="Blue" value="blue" />    
 <asp:ListItem Text="Green" value="green" />    
</asp:DropDownList>

The most useful event that this control provides is SelectedIndexChanged. This event is also exposed by other list controls, such as the CheckBoxList and RadioButtonList controls, allowing for easy programmatic interaction with the control you’re using. These controls can also be bound to a database and used to extract dynamic content into a drop-down menu.

ListBox

A ListBox control equates to the HTML select element with either the multiple or size attribute set (size would need to be set to a value of 2 or more). If you set the SelectionMode attribute to Multiple, the user will be able to select more than one item from the list, as in this example:

<asp:ListBox id="listTechnologies" runat="server"     
   SelectionMode="Multiple">    
 <asp:ListItem Text="ASP.NET" Value="aspnet" />    
 <asp:ListItem Text="JSP" Value="jsp" />    
 <asp:ListItem Text="PHP" Value="php" />    
 <asp:ListItem Text="CGI" Value="cgi" />    
 <asp:ListItem Text="ColdFusion" Value="cf" />    
</asp:ListBox>

RadioButtonList

Like the RadioButton control, the RadioButtonList control represents radio buttons. However, the RadioButtonList control represents a list of radio buttons and uses more compact syntax. Here’s an example:

<asp:RadioButtonList id="favoriteColor" runat="server">    
 <asp:ListItem Text="Red" Value="red" />    
 <asp:ListItem Text="Blue" Value="blue" />    
 <asp:ListItem Text="Green" Value="green" />    
</asp:RadioButtonList>

CheckBoxList

As you may have guessed, the CheckBoxList control represents a group of check boxes; it’s equivalent to using several CheckBox controls in a row:

<asp:CheckBoxList id="favoriteFood" runat="server">    
 <asp:ListItem Text="Pizza" Value="pizza" />    
 <asp:ListItem Text="Tacos" Value="tacos" />    
 <asp:ListItem Text="Pasta" Value="pasta" />    
</asp:CheckBoxList>

BulletedList

The BulletedList control displays bulleted or numbered lists, using <ul> (unordered list) or <ol> (ordered list) tags. Unlike the other list controls, the BulletedList doesn’t allow the selection of items, so the SelectedIndexChanged event isn’t supported.

The first property you’ll want to set is DisplayMode, which can be Text(the default), or HyperLink, which will render the list items as links. When DisplayMode is set to HyperLink, you can use the Click event to respond to a user’s click on one of the items.

The other important property is BulletStyle, which determines the style of the bullets. The accepted values are:

  • Numbered (1, 2, 3, …)
  • LowerAlpha (a, b, c, …)
  • UpperAlpha (A, B, C, …)
  • LowerRoman (i, ii, iii, …)
  • UpperRoman (I, II, III, …)
  • Circle
  • Disc
  • Square
  • CustomImage

If the style is set to CustomImage, you’ll also need to set the BulletStyleImageUrl to specify the image to be used for the bullets. If the style is one of the numbered lists, you can also set the FirstBulletNumber property to specify the first number or letter that’s to be generated.

Advanced Controls

These controls are advanced in terms of their usage, the HTML code they generate, and the background work they do for you. Some of these controls aren’t available to older versions of ASP.NET.

Calendar

The Calendar is a great example of the reusable nature of ASP.NET controls. The Calendar control generates markup that displays an intuitive calendar in which the user can click to select, or move between, days, weeks, months, and so on.

The Calendar control requires very little customization. In Visual Web Developer, select Website > Add New Item..., and make the changes indicated:

Visual Basic LearningASPVBCalendar_01.aspx
<%@ Page Language="VB" %>    
   
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">    
   
<script runat="server">    
   
</script>    
   
<html xmlns="http://www.w3.org/1999/xhtml">    
 <head runat="server">    
   <title>Calendar Test/title>    
 </head>    
 <body>    
   <form id="form1" runat="server">    
   <div>    
     <asp:Calendar ID="myCalendar" runat="server" />    
   </div>    
   </form>    
 </body>    
</html>    

Again, the C# version is the same, except for the Page declaration:

C# LearningASPCS1_Calendar.aspx (excerpt)

<%@ Page Language="C#" %>
...

If you save this page in your working folder and load it, you’ll see the output shown in Figure 4.

Displaying the default calendar

The Calendar control contains a wide range of properties, methods, and events, including those listed in Table 3.

Table 3. Some of the Calendar control’s properties

Property Description
DayNameFormat This property sets the format of the day names. Its possible values are
FirstLetter, FirstTwoLetters, Full, and Short. The default
is Short, which displays the three-letter abbreviation.
FirstDayOfWeek This property sets the day that begins each week in the calendar. By default,
the value of this property is determined by your server’s region settings,
but you can set this to Sundayor Monday if you want to control it.
NextPrevFormat Set to CustomText by default, this property can be set to ShortMonth
or FullMonth to control the format of the next and previous month
links.
SelectedDate This property contains a DateTime value that specifies the highlighted day.
You’ll use this property often, to determine which date the user has
selected.
SelectionMode This property determines whether days, weeks, or months can be selected;
its possible values are Day, DayWeek, DayWeekMonth, and None, and
the default is Day. When Dayis selected, a user can only select a day;
when DayWeek is selected, a user can select a day or an entire week; and
so on.
SelectMonthText This property controls the text of the link that’s displayed to allow users
to select an entire month from the calendar.
SelectWeekText This property controls the text of the link that’s displayed to allow users
to select an entire week from the calendar.
ShowDayHeader If True, this property displays the names of the days of the week. The
default is True.
ShowGridLines If True, this property renders the calendar with grid lines. The default is
True.
ShowNextPrevMonth If True, this property displays next month and previous month links.
The default is True.
ShowTitle If True, this property displays the calendar’s title. The default is False
TitleFormat This property determines how the month name appears in the title bar.
Possible values are Monthand MonthYear. The default is MonthYear.
TodaysDate This DateTime value sets the calendar’s current date. By default, this value
is not highlighted within the Calendar control.
VisibleDate This DateTime value controls which month is displayed.

Let’s take a look at an example that uses some of these properties, events, and methods to create a Calendar control which allows users to select days, weeks, and months. Modify the calendar in Calendar.aspx (both the VB and C# versions), and add a label to it, as follows:

LearningASPVBCalendar_02.aspx (excerpt)
...    
   <form id="form1" runat="server">    
   <div>    
     <h1>Pick your dates:</h1>    
     <asp:Calendar ID="myCalendar" runat="server"    
         DayNameFormat="Short" FirstDayOfWeek="Sunday"    
         NextPrevFormat="FullMonth" SelectionMode="DayWeekMonth"    
         SelectWeekText="Select Week"    
         SelectMonthText="Select Month" TitleFormat="Month"    
         OnSelectionChanged="SelectionChanged" />    
     <h1>You selected these dates:</h1>    
     <asp:Label ID="myLabel" runat="server" />
   
   </div>    
   </form>    
...

Now edit the <script runat="server"> tag to include the SelectionChanged event handler referenced by your calendar:

Visual Basic LearningASPVBCalendar_02.aspx (excerpt)
<script runat="server">    
 Sub SelectionChanged(ByVal s As Object, ByVal e As EventArgs)    
   myLabel.Text = ""    
   For Each d As DateTime In myCalendar.SelectedDates    
     myLabel.Text &= d.ToString("D") & "<br />"    
   Next    
 End Sub
   
</script>

C# LearningASPCSCalendar_02.aspx (excerpt)
<script runat="server">    
 void SelectionChanged(Object s, EventArgs e)    
 {    
   myLabel.Text = "";    
   foreach (DateTime d in myCalendar.SelectedDates)    
   {    
     myLabel.Text += d.ToString("D") + "<br />";    
   }    
 }
   
</script>

Save your work and test it in a browser. Try selecting a day, week, or month. The selection will be highlighted in a similar way to the display shown in Figure 5.

Using the Calendar control

In SelectionChanged, we loop through each of the dates that the user has selected, and append each to the Label we added to the page.

AdRotator

The AdRotator control allows you to display a list of banner advertisements at random within your web application. However, it’s more than a mere substitute for creating a randomization script from scratch. Since the AdRotator control gets its content from an XML file, the administration and updating of banner advertisement files and their properties is a snap. Also, the XML file allows you to control the banner’s image, link, link target, and frequency of appearance in relation to other banner ads.

The benefits of using this control don’t stop there, though. Most of the AdRotator control’s properties reside within an XML file; if you wanted to, you could share that XML file on the Web, allowing value added resellers (VARS), or possibly your companies’ partners, to use your banner advertisements on their web sites.

NOTE: What Is XML?
In essence, XML is simply a text-based format for the transfer or storage of data; it contains no details about how that data should be presented. XML is very easy to start with because of its close resemblance to your old friend HTML: both are largely comprised of tags inside angle brackets (< and >), and any tag may contain attributes that are specific to that tag. The biggest difference between XML and HTML is that, rather than providing a fixed set of tags as HTML does, XML allows us to create our own tags to describe the data we wish to represent.

Take a look at the following HTML element:

<h1>Star Wars Episode I: The Phantom Menace</h1> 

This example describes the content between the tags as a level one heading. This is fine if all we want to do is display the heading "Star Wars Episode I: The Phantom Menace" on a web page. But what if we want to access those words as data?

Like HTML, XML's purpose is to describe the content of a document. But where HTML is a very generic markup language for documents - headings, paragraphs and lists, for example - XML can, very specifically, describe what the content is. Using XML, the web author can mark up the contents of a document, describing that content in terms of its relevance as data.

We can use XML to mark up the words "Star Wars Episode I: The Phantom Menace" in a way that better reflects this content's significance as data:

<film>     
 <title>Star Wars Episode I: The Phantom Menace</title>    
</film>

Here, the XML tag names we've chosen best describe the contents of the element. We also define our own attribute names as necessary. For instance, in the example above, you may decide that you want to differentiate between the VHS version and the DVD version of the film, or record the name of the movie's director. This can be achieved by adding attributes and elements, as shown below:

<film format="DVD">    
 <title>Star Wars Episode I: The Phantom Menace</title>    
 <director>George Lucas</director>    
</film>

If you want to test this control out, create a file called ads.xml in your LearningASPVB or /#c#/LearningASPCS folder (or both), and insert the content presented below. Feel free to create your own banners, or to use those provided in the code archive for this book:

LearningASPVBAds.xml
<?xml version="1.0" encoding="utf-8" ?>    
<Advertisements>    
 <Ad>    
   <ImageUrl>workatdorknozzle.gif</ImageUrl>    
   <NavigateUrl>http://www.example.com</NavigateUrl>    
   <TargetUrl>_blank</TargetUrl>    
   <AlternateText>Work at Dorknozzle!</AlternateText>    
   <Keyword>HR Sites</Keyword>    
   <Impressions>2</Impressions>    
 </Ad>    
 <Ad>    
   <ImageUrl>getthenewsletter.gif</ImageUrl>    
   <NavigateUrl>http://www.example.com</NavigateUrl>    
   <TargetUrl>_blank</TargetUrl>    
   <AlternateText>Get the Nozzle Newsletter!</AlternateText>    
   <Keyword>Marketing Sites</Keyword>    
   <Impressions>1</Impressions>    
 </Ad>    
</Advertisements>

As you can see, the Advertisements element is the root node, and in accordance with the XML specification, it appears only once. For each individual advertisement, we simply add an Ad child element. For instance, the above advertisement file contains details for two banner advertisements.

As you've probably noticed by now, the .xml file enables you to specify properties for each banner advertisement by inserting appropriate elements inside each of the Ad elements. These elements include:

ImageURL
the URL of the image to display for the banner ad
NavigateURL
the web page to which your users will navigate when they click the banner ad
AlternateText
the alternative text to display for browsers that don't support images
Keyword
the keyword to use to categorize your banner ad
(If you use the KeywordFilter property of the AdRotator control, you can specify the categories of banner ads to display.)
Impressions
the relative frequency with which a particular banner ad should be shown in relation to other banner advertisements
(The higher this number, the more frequently that specific banner will display in the browser. The number provided for this element can be as low as one, but cannot exceed 2,048,000,000; if it does, the page throws an exception.)

Except for ImageURL, all these elements are optional. Also, if you specify an Ad without a NavigateURL, the banner ad will display without a hyperlink.

To make use of this Ads.xml file, create a new ASP.NET page called AdRotator.aspx, and add the following code to it:

Visual Basic LearningASPVBAdRotator.aspx
<%@ Page Language="VB" %>    
   
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    
   "htt;p://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">    
   
<script runat="server">    
   
</script>    
   
<html xmlns="http://www.w3.org/1999/xhtml">    
 <head runat="server">    
   <title>Using the AdRotator Control</title>    
</head>    
<body>    
   <form id="form1" runat="server">    
   <div>    
     <asp:AdRotator ID="adRotator" runat="server"    
       AdvertisementFile="Ads.xml" />
   
   </div>    
   </form>    
 </body>    
</html>

As with most of our examples, the C# version of this code is the same except for the Page declaration. You’ll also need to copy the workatdorknozzle.gif and getthenewsletter.gif image files from the code archive and place them in your working folder in order to see these ad images. Save your work and test it in the browser; the display should look something like Figure 6.

Displaying ads using AdRotator.aspx

Refresh the page a few times, and you’ll notice that the first banner appears more often than the second. This occurs because the Impression value for the first Ad is double the value set for the second banner, so it will appear twice as often.

TreeView

The TreeView control is a very powerful control that’s capable of displaying a complex hierarchical structure of items. Typically, we’d use it to view a directory structure or a site navigation hierarchy, but it could be used to display a family tree, a corporate organizational structure, or any other hierarchical structure.

The TreeView can pull its data from various sources. We’ll talk more about the various kinds of data sources later in the book; here, we’ll focus on the SiteMapDataSource class, which, as its name suggests, contains a hierarchical sitemap. By default, this sitemap is read from a file called Web.sitemap that’s located in the root of your project (you can easily create this file using the Site Map template in Visual Web Developer). Web.sitemap is an XML file that looks like this:

LearningASPVBWeb.sitemap
<siteMap    
   xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">    
 <siteMapNode title="Home" url="~/Default.aspx"    
     description="Home">    
   <siteMapNode title="SiteMapPath" url="~/SiteMapPath.aspx"      
       description="TreeView Example" />    
   <siteMapNode title="TreeView" url="~/TreeViewSitemap.aspx"      
       description="TreeView Example" />    
   <siteMapNode title="ClickEvent" url="~/ClickEvent.aspx"    
       description="ClickEvent Example" />    
   <siteMapNode title="Loops"  url="~/Loops.aspx"    
       description="Loops Example" />    
 </siteMapNode>    
</siteMap>    

NOTE: A Web.sitemap Limitation
An important limitation to note when you’re working with Web.sitemap files is that they must contain only one siteMapNode as the direct child of the root siteMap element.

In the example above, the siteMapNode with the title Home is this single siteMapNode. If we added another siteMapNodealongside (rather than inside) this element, the Web.sitemap file would no longer be valid.

To use this file, you’ll need to add a SiteMapDataSource control to the page, as well as a TreeView control that uses this data source, like this:

Visual Basic LearningASPVBTreeViewSiteMap.aspx
<%@ Page Language="VB" %>    
   
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"      
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">    
   
<script runat="server">    
   
</script>    
   
<html xmlns="http://www.w3.org/1999/xhtml">    
 <head runat="server">    
   <title>TreeView Demo</title>    
 </head>    
 <body>    
   <form id="form1" runat="server">    
   <div>    
     <asp:SiteMapDataSource ID="mySiteMapDataSource"      
         runat="server" />    
     <asp:TreeView ID="myTreeView" runat="server"      
         DataSourceID="mySiteMapDataSource" />
     
   </div>    
   </form>    
 </body>    
</html>

Note that although the SiteMapDataSource is a control, it doesn’t generate any HTML within the web page. There are many data source controls like this; we’ll delve into them in more detail later.

When combined with the example Web.sitemap file above, this web form would generate an output like that shown in Figure 7.

A simple TreeView control

As you can see, the TreeView control generated the tree for us. The root Home node can even be collapsed or expanded.

In many cases, we won’t want to show the root node; we can hide it from view by setting the ShowStartingNode property of the SiteMapDataSource to false:

<asp:SiteMapDataSource ID="mySiteMapDataSource"runat="server"     
   ShowStartingNode="false" />
SiteMapPath

The SiteMapPath control provides the functionality to generate a breadcrumb navigational structure for your site. Breadcrumb systems help to orientate users, giving them an easy way to identify their current location within the site, and providing handy links to the current location’s ancestor nodes. An example of a breadcrumb navigation system is shown in Figure 8.

A breadcrumb created using the SiteMapPath control

The SiteMapPath control will automatically use any SiteMapDataSource control that exists in a web form, such as the TreeView control in the previous example, to display a user’s current location within the site. For example, you could simply add the following code to a new web form to achieve the effect shown in Figure 8:

Visual Basic LearningASPVBSiteMapPath.aspx
<%@ Page Language="VB" %>    
   
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">    
   
<script runat="server">    
   
</script>    
   
<html xmlns="http://www.w3.org/1999/xhtml">    
 <head runat="server">    
   <title>SiteMapPath Demo</title>    
 </head>    
 <body>    
   <form id="form1" runat="server">    
   <div>    
     <asp:SiteMapDataSource ID="mySiteMapDataSource"    
         runat="server" />    
     <asp:SiteMapPath ID="mySiteMapPath" runat="server"    
         DataSourceID="mySiteMapDataSource"    
         PathSeparator=" > " />
   
   </div>    
   </form>    
 </body>    
</html>

Note that the SiteMapPath control allows you to customize the breadcrumbs’ separator character via the PathSeparator property. Also note that if you don’t have a file named Default.aspx in the directory, the root node link won’t work.

Menu

The Menu control is similar to TreeView in that it displays hierarchical data from a data source; the ways in which we work with both controls are also very similar. The most important differences between the two lie in their appearances, and the fact that Menu supports templates for better customization, and displays only two levels of items (menu items and submenu items).

MultiView

The MultiView control is similar to Panel in that it doesn’t generate interface elements itself, but contains other controls. However, a MultiView can store more pages of data (called views), and lets you show one page at a time. You can change the active view (the one that’s being presented to the visitor) by setting the value of the ActiveViewIndex property. The first page corresponds to an ActiveViewIndex of 0; the value of the second page is 1; the value of the third page is 2; and so on.

The contents of each template are defined inside child View elements. Consider the following code example, which creates a Button control and a MultiView control:

Visual Basic Learning ASPVBMultiView.aspx
<%@ Page Language="VB" %> <!DOCTYPE      
   
<%@ Page Language="VB" %>    
   
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">    
   
<script runat="server">    
 Sub SwitchPage(s as Object, e as EventArgs)      
   myMultiView.ActiveViewIndex = _    
       (myMultiView.ActiveViewIndex + 1) Mod 2    
 End Sub
   
</script>    
   
<html xmlns="http://www.w3.org/1999/xhtml">    
 <head runat="server">    
   <title>MultiView Demo</title>    
 </head>    
 <body>    
   <form id="form1" runat="server">    
   <div>    
     <p>    
       <asp:Button ID="myButton" Text="Switch Page"    
           runat="server" OnClick="SwitchPage" />    
     </p>    
     <asp:MultiView ID="myMultiView" runat="server"    
         ActiveViewIndex="0">    
       <asp:View ID="firstView" runat="server">    
         <p>... contents of the first view ...</p>    
       </asp:View>    
       <asp:View ID="secondView" runat="server">    
         <p>... contents of the second view ...</p>    
       </asp:View>    
     </asp:MultiView>
   
   </div>    
   </form>    
 </body>    
</html>

LearningASPCSMultiView.aspx (excerpt)
<%@ Page Language="C#" %>    
...    
<script runat="server">    
 public void SwitchPage(Object s, EventArgs e)    
 {    
   myMultiView.ActiveViewIndex =    
       (myMultiView.ActiveViewIndex + 1) % 2;    
 }
   
</script>    
...

As you can see, by default, the ActiveViewIndex is 0, so when this code is first executed, the MultiView will display its first template, which is shown in Figure 9.

Using the MultiView control

Clicking on the button will cause the second template to be displayed. The SwitchPage event handler uses the modulo operator, Mod in VB and % in C#, to set the ActiveViewIndex to 1 when its original value is 0, and vice versa.

The MultiView control has a number of other handy features, so be sure to check the documentation for this control if you’re using it in a production environment.

Wizard

The Wizard control is a more advanced version of the MultiView control. It can display one or more pages at a time, but also includes additional built-in functionality such as navigation buttons, and a sidebar that displays the wizard’s steps.

FileUpload

The FileUpload control allows you to let visitors upload files to your server. We go into this control in more detail in Chapter 14 of this book.

Web User Controls

As you build real-world projects, you’ll frequently encounter pieces of the user interface that appear in multiple places – headers or footers, navigation links, and login boxes are just a few examples. Packaging their forms and behaviors into your own controls will allow you to reuse these components just as you can reuse ASP.NET’s built-in controls.

Building your own web server controls involves writing advanced VB or C# code, and is not within the scope of this book, but it’s good to know that it’s possible. Creating customized web server controls makes sense when you need to build more complex controls that provide a high level of control and performance, or you want to create controls that can be integrated easily into many projects.

Those of us without advanced coding skills can develop our own controls by creating web user controls. These are also powerful and reusable within a given project; they can expose properties, events, and methods, just like other controls; and they’re easy to implement.

A web user control is represented by a class that inherits from System.Web.UI.UserControl, and contains the basic functionality that you need to extend to create your own controls. The main drawback to using web user controls is that they’re tightly integrated into the projects in which they’re implemented. As such, it’s more difficult to distribute them, or include them in other projects, than it is to distribute or reuse web server controls.

Web user controls are implemented very much like normal web forms – they’re comprised of other controls, HTML markup, and server-side code. The file extension of a web user control is .ascx.

Creating a Web User Control

Let’s get a feel for web user controls by stepping through a simple example. Let’s say that in your web site, you have many forms consisting of pairs of Label and TextBox controls, like the one shown in Figure 10.

A simple form

All the labels must have a fixed width of 100 pixels, and the text boxes must accept a maximum of 20 characters.

Rather than adding many labels and text boxes to the form, and then having to set all their properties, let’s make life easier by building a web user control that includes a Label of the specified width, and a TextBox that accepts 20 characters; you’ll then be able to reuse the web user control wherever it’s needed in your project.

Create a new file in your working project using the Web User Control template, as shown in Figure 11.

Creating a new Web User Control

Name the file SmartBox.ascx. Then, add the control’s constituent controls – a Label control and a TextBox control – as shown below (for both VB and C# versions):

Visual Basic LearningASPVBSmartBox.ascx (excerpt)
<%@ Control Language="VB" ClassName="SmartBox" %>      
     
<script runat="server">      
...        
</script>      
     
<p>      
 <asp:Label ID="myLabel" runat="server" Text="" Width="100" />      
 <asp:TextBox ID="myTextBox" runat="server" Text="" Width="200"      
     MaxLength="20" />
     
</p>

NOTE: Label Widths in Firefox
Unfortunately, setting the Width property of the Label control doesn’t guarantee that the label will appear at that width in all browsers. The current version of Firefox, for example, will not display the above label in the way it appears in Internet Explorer.

To get around this pitfall, you should use a CSS style sheet and the CssClass property, which we’ll take a look at later in this chapter.

As a web user control is a class, it can also have methods, properties, and so on. Our SmartBox control extends the base System.Web.UI.UserControl class by adding two properties:

  • LabelText is a write-only property that allows the forms using the control to set the control’s label text.
  • Text is a read-only property that returns the text the user typed into the text box.

Let’s add a server-side script element that will give our control two properties – one called Text, for the text in the TextBox, and one called LabelText, for the text in the Label:

Visual Basic Learning ASPVBSmartBox.ascx (excerpt)
<%@ Control Language="VB" ClassName="SmartBox" %>      
     
<script runat="server">      
 Public WriteOnly Property LabelText() As String      
   Set(ByVal value As String)      
     myLabel.Text = value      
   End Set      
 End Property      
       
 Public ReadOnly Property Text() As String      
   Get      
     Text = myTextBox.Text      
   End Get      
 End Property
     
</script>      
     
<p>      
 <asp:Label ID="myLabel" runat="server" Text="" Width="100" />      
 <asp:TextBox ID="myTextBox" runat="server" Text="" Width="200"      
     MaxLength="20" />      
</p>

C# Learning ASPCSSmartBox.ascx (excerpt)
<%@ Control Language="C#" ClassName="SmartBox" %>      
     
<script runat="server">      
 public string LabelText      
 {      
   set      
   {      
     myLabel.Text = value;      
   }      
 }      
 public string Text      
 {      
   get      
   {      
     return myTextBox.Text;      
   }      
 }
     
</script>      
     
<p>      
 <asp:Label ID="myLabel" runat="server" Text="" Width="100" />      
 <asp:TextBox ID="myTextBox" runat="server" Text="" Width="200"      
     MaxLength="20" />      
</p>

Just like web forms, web user controls can work with code-behind files, but, in an effort to keep our examples simple, we aren’t using them in this chapter.

When you use the SmartBox control in a form, you can set its label and have the text entered by the user, like this:

Visual Basic
mySmartBox.LabelText = "Address:"
userAddress = mySmartBox.Text

C#
mySmartBox.LabelText = "Address:";
userAddress = mySmartBox.Text;

Let’s see how we implemented this functionality. In .NET, properties can be read-only, write-only, or read-write. In many cases, you’ll want to have properties that can be both readable and writeable, but in this case, we want to be able to set the text of the inner Label, and to read the text from the TextBox.

To define a write-only property in VB, you need to use the WriteOnly modifier. Write-only properties need only define a special block of code that starts with the keyword Set. This block of code, called an accessor, is just like a subroutine that takes as a parameter the value that needs to be set. The block of code uses this value to perform the desired action – in the case of the LabelText property, the action sets the Text property of our Label control, as shown below:

Visual Basic LearningASPVBSmartBox.ascx (excerpt)
Public WriteOnly Property LabelText() As String      
 Set(ByVal value As String)      
   myLabel.Text = value      
 End Set      
End Property

Assuming that a form uses a SmartBox object called mySmartBox, we could set the Text property of the Label like this:

Visual Basic
mySmartBox.LabelText = "Address:"

When this code is executed, the Set accessor of the LabelText property is executed with its value parameter set to Address:. The Set accessor uses this value to set the Text property of the Label.

The other accessor you can use when defining properties is Get, which allows us to read values instead of writing them. Obviously, you aren’t allowed to add a Get accessor to a WriteOnly property, but one is required for a ReadOnly property, such as Text:

Visual Basic LearningASPVBSmartBox.ascx (excerpt)
Public ReadOnly Property Text() As String      
 Get      
   Text = myTextBox.Text      
 End Get      
End Property      

The Text property is ReadOnly, but it doesn’t need to be. If you wanted to allow the forms using the control to set some default text to the TextBox, you’d need to add a Set accessor, and remove the ReadOnly modifier.

When you’re defining a property in C#, you don’t need to set any special modifiers, such as ReadOnly or WriteOnly, for read-only or write-only properties. A property that has only a get accessor will, by default, be considered read-only:

C# LearningASPCSSmartBox.ascx (excerpt)
public string Text      
{      
 get      
 {      
   return myTextBox.Text;      
 }      
}

Likewise, a property that has only a set accessor will be considered to be write-only:

C# LearningASPCSSmartBox.ascx (excerpt)
public string LabelText      
{      
 set      
 {      
   myLabel.Text = value;      
 }      
}

x
Using the Web User Control

Once the user control has been created, it can be referenced from any ASP.NET page using the Register directive, as follows:

<%@ Register TagPrefix="prefix" TagName="name"      
   Src="source.ascx" %>

The Register directive requires three attributes:

TagPrefix
the prefix for the user control, which allows you to group related controls together, and avoid naming conflicts

TagName
the control's tag name, which will be used when the control is added to the ASP.NET page

Src
the path to the .ascx file that describes the user control

After we register the control, we create instances of it using the <TagPrefix:TagName> format. Let's try an example that uses the SmartBox control. Create a Web Form named ControlTest.aspx in your project folder, and give it this content:

Visual Basic LearningASPVBControlTest.aspx
<%@ Page Language="VB" %>        
<%@Register TagPrefix="sp" TagName="SmartBox"      
   Src="SmartBox.ascx" %>      
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"      
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">      
     
<script runat="server">      
     
</script>      
     
<html xmlns="http://www.w3.org/1999/xhtml">      
 <head runat="server">      
   <title>Creating ASP.NET Web Server Controls</title>      
 </head>      
 <body>      
   <form id="form1" runat="server">      
   <div>      
     <sp:SmartBox ID="nameSb" runat="server"      
         LabelText="Name:" />      
     <sp:SmartBox ID="addressSb" runat="server"      
         LabelText="Address:" />      
     <sp:SmartBox ID="countrySb" runat="server"      
         LabelText="Country:" />      
     <sp:SmartBox ID="phoneSb" runat="server"      
         LabelText="Phone:" />
     
   </div>      
   </form>      
 </body>      
</html>

Creating this page by hand will really help you to understand the process of building a web form. In time, you'll learn how to use Visual Web Developer to do part of the work for you. For example, you can drag a user control from Solution Explorer and drop it onto a web form; Visual Web Developer will register the control and add an instance of the control for you. Loading this page will produce the output we saw in Figure 10.

Now, this is a very simple example indeed, but we can easily extend it for other purposes. You can see in the above code snippet that we set the LabelText property directly using the control's attributes; however, we could have accessed the properties from our code instead. Here's an example of in which we set the LabelText properties of each of the controls using VB and C#:

Visual Basic
<script runat="server">      
 Protected Sub Page_Load()      
   nameSb.LabelText = "Name:"      
   addressSb.LabelText = "Address:"      
   countrySb.LabelText = "Country:"      
   phoneSb.LabelText = "Phone:"      
 End Sub      
</script>

C#
script runat="server">      
 protected void Page_Load()      
 {      
   nameSb.LabelText = "Name:";      
   addressSb.LabelText = "Address:";      
   countrySb.LabelText = "Country:";      
   phoneSb.LabelText = "Phone:";      
 }      
</script>

Master Pages

Master pages are an important feature that was introduced in ASP.NET 2.0. Master pages are similar to web user controls in that they, too, are composed of HTML and other controls; they can be extended with the addition of events, methods, or properties; and they can’t be loaded directly by users – instead, they’re used as building blocks to design the structure of your web forms.
A master page is a page template that can be applied to give many web forms a consistent appearance. For example, a master page can set out a standard structure containing the header, footer, and other elements that you expect to display in multiple web forms within a web application.

Master page files have the .master extension, and, just like web forms and web user controls, they support code-behind files. All master pages inherit from the class System.Web.UI.MasterPage.

Designing a site structure using master pages and web user controls gives you the power to modify and extend the site easily. If your site uses these features in a well-planned way, it can be very easy to modify certain details of the layout or functionality of your site, because updating a master page or a web user control takes immediate effect on all the web forms that use the file.

As we’ve already mentioned, a master page is built using HTML and controls, including the special ContentPlaceHolder control. As its name suggests, the ContentPlaceHolder is a placeholder that can be filled with content that’s relevant to the needs of each web form that uses the master page. In creating a master page, we include all of the basic structure of future pages in the master page itself, including the <html>, <head>, and <body> tags, and let the web forms specify the content that appears in the placeholders.

Let’s see how this works with a simple example. Suppose we have a site with many pages, all of which contain a standard header, footer, and navigation menu, laid out as per the wireframe shown in Figure 12.

A simple web site layout

If all the pages in the site have the same header, footer, and navigation menu, it makes sense to include these components in a master page, and to build several web forms that customize only the content areas on each page.

To keep this example simple, we won’t include a menu here: we’ll include just the header, the footer, and the content placeholder. Add a new file to your project using the Master Page template in Visual Web Developer. Name the file FrontPages.master, as shown in Figure 13, and select the appropriate language. You’ll notice that some <asp:ContentPlaceHolder> tags have been created for you already, one in the <head>, and one in the page body. You can remove them and modify the page like this:

Visual Basic LearningASPVBFrontPages.master
<%@ Master Language="VB" %>      
     
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"      
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">      
     
<script runat="server">      
     
</script>      
     
<html xmlns="http://www.w3.org/1999/xhtml">      
 <head runat="server">      
   <title>Untitled Page</title>      
 </head>      
 <body>      
   <form id="form1" runat="server">      
   <div>      
     <h1>Welcome to SuperSite Inc!</h1>      
     <asp:ContentPlaceHolder ID="FrontPageContent"      
         runat="server" />      
     <p>Copyright 2006</p>        
   </div>      
   </form>      
 </body>      
</html>

Again, the C# version is identical except for the Master declaration at the top of the page:

C# LearningASPCSFrontPages.master (excerpt)
<%@ Master Language="C#" %>
...

Creating a Master Page

The master page looks almost like a web form, except for one important detail: it has an empty ContentPlaceHolder control. If you want to build a web form based on this master page, you just need to reference the master page using the Page directive in the web form, and add a Content control that includes the content you want to insert.

Let’s try it. Create a web form in Visual Web Developer called FrontPage.aspx, and check the Select master page option. This option will allow you to choose a master page for the form; Visual Web Developer will then use that master page to generate the code for you. Edit it to match this code snippet:

Visual Basic LearningASPVBFrontPage.aspx (excerpt)
<%@ Page Language="VB" MasterPageFile="~/FrontPages.master"      
   Title="Front Page" %>      
     
<script runat="server">      
     
</script>      
     
<asp:Content ID="Content1" ContentPlaceHolderID="FrontPageContent"      
   Runat="Server">      
 <p>      
   Welcome to our web site! We hope you'll enjoy your visit.      
 </p>      
</asp:Content>

The VB and C# versions of this code are the same except for the Language attribute on the Page declaration, but because Visual Web Developer generates all the code for you automatically, you don’t need to worry about it – instead, you can focus on the content.

You’re all set now! Executing FrontPage.aspx will generate the output shown in Figure 14.

Using a master page to set the header and footer

Although the example is simplistic, it’s easy to see the possibilities: you can create many web forms based on this template very easily. In our case, the master page contains a single ContentPlaceHolder, but it could have more. Also, we can define within the master page default content for display inside the ContentPlaceHolder on pages whose web forms don’t provide a Content element for that placeholder.

We’ll explore Visual Web Developer’s capabilities in more depth in the following chapters, but for now you can play around with it yourself, using Design mode to visually edit web forms that are based on master pages. Looking at Figure 15, you can see that the content of the master page is read-only, and that you can edit only the content areas of the page.

Design mode shows the editable areas of a form that uses a master page

Summary

In this chapter, we discussed web forms, HTML server controls, web server controls, web user controls, master pages, and CSS. All these elements can be combined to create powerful structures for your web sites.

In the next chapter, we start building “real” web applications, putting into practice most of the theory you’ve learned so far, and using a professional development environment that will do part of the work for you – and all this can be found in Build Your Own ASP.NET 3.5 Web Site Using C# & VB, in stock now!

No Reader comments

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Front-end, once a week, for free.