from SitePoint
Chapter 4: Constructing ASP.NET Web Pages
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 many techniques that allow web developers to build parts of web pages independently, then put them together later to build complete pages.
The content we’re organizing 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, 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.
Web Forms
As you know, there’s always new terminology to master when you’re learning new technologies. But with ASP.NET, even the simplest terms that are used to describe the basics of web pages change to reflect the processes that occur within them.
The term used to describe an ASP.NET web page is web form, and this is the central object in ASP.NET development. You’ve already met web forms–they’re the .aspx
files you’ve worked with so far in this book. At first glance, web forms look much like HTML pages, but in addition to static HTML content they also contain ASP.NET presentational elements, and code that executes on the server side to generate dynamic content and perform the desired server-side functionality.
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:
<html>
<head>
<script runat="server" language="language">
...code here...
</script>
</head>
<body>
<form runat="server">
...user interface elements here...
</form>
</body>
</html>
To access and manipulate a web form programatically, we use the System.Web.UI.Page
class. You might recognize this class from the code-behind example we saw in Chapter 3, VB and C# Programming Basics. We must mention the class explicitly in the code-behind file. In situations in which we’re not using code-behind files (i.e. we write 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 programatically. 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 4.1.
Figure 1: Table 4.1. HTML control classes
For more details on these classes, see Appendix A.
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, then 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 Learning
folder you created in Chapter 1. The following code creates the visual interface for the survey:
Example 4.1. Survey.aspx (excerpt)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Using ASP.NET HTML Server Controls</title>
<!-- code will go here -->
</head>
<body>
<form runat="server">
<h2>Take the Survey!</h2>
<!-- 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>
</form>
</body>
</html>
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 HtmlInputText
controls, an HtmlButton
control, 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.
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.
When it’s complete, the Survey.aspx
web form will resemble Figure 4.1.
Figure 4.1. A simple form that uses HTML server controls
When a user clicks on the 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, we’d access the properties of the HTML controls as shown below:
Example 4.2. Survey.aspx (excerpt)
<script runat="server" language="VB">
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>
Example 4.3. Survey.aspx (excerpt)
<script runat="server" language="C#">
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 in previous chapters, we start by placing our VB and C# code inside a server-side script block within the <head>
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.
Figure 4.2. Viewing the survey results
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 4.2.
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 them using VB or C# code on the server side.
Web Server Controls
Web server controls can be seen as more 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:
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:
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, Microsoft has basically reinvented HTML from scratch.
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 (e.g. 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. So, 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 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 of the web server controls as we work through this and future chapters.
For more information on web server controls, including the properties, methods, and events for each, have a look at Appendix B.
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 2.0 SDK Documentation whenever you need more details about any of the framework’s
classes (or controls). Access the documentation from Start > All Programs > Microsoft .NET Framework SDK v2.0 >
Documentation. 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
three classes named Label
, situated in the System.Web.UI.MobileControls
,
System.Web.UI.WebControls
, and System.Windows.Forms
namespaces, as Figure 4.3 illustrates. You’ll most likely be interested in the version of the class situated in the WebControls
namespace.
Figure 4.3. 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 any 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":
Public Sub Page_Load()
messageLabel.Text = "Hello World"
End Sub
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. Using the TextMode
property, this control can be set 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 attribute TextMode
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:
Public Sub WriteText(s As Object, e As EventArgs)
messageLabel.Text = "Hello World"
End Sub
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:
Public Sub WriteText(s As Object, e As ImageClickEventArgs)
messageLabel.Text = "Coordinate: " & e.X & "," & e.Y
End Sub
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.
<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="I agree, I like .NET!"
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 RadioButton
s can be grouped together to represent a set of options from which only one can be selected. Radio buttons are grouped together using the GroupName
property.
<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 RadioButton
s 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 differently when clicked by the user.
These areas are defined using three controls that 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>
Possible values of HotSpotMode
, and the bahavior of each, include:
Inactive
– Exhibits no behavior when hotspot is clicked.Navigate
– The user is navigated to the specified URL.NotSet
– When set for a HotSpot, the behavior is inherited from the parentImageMap
; if the parentImageMap
doesn’t specify a default value,Navigate
is set. When set for anImageMap
, this value is effectively equivalent toNavigate
.PostBack
– The hot spot raises theClick
event that can be handled 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 the list above. 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 2.0 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.
<asp:PlaceHolder id="placeHolder" runat="server" />
The following code dynamically adds a new HtmlButton
control within the placeholder:
Public Sub Page_Load()
Dim button myButton As HtmlButton = New HtmlButton()
myButton.InnerText = "My New Button"
placeHolder.Controls.Add(myButton)
End Sub
public void Page_Load()
{
HtmlButton button myButton = new HtmlButton();
myButton.InnerText = "My New Button";
placeHolder.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
:
Public Sub HidePanel(s As Object, e As EventArgs)
myPanel.Visible = False
End Sub
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.
<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 exposed by other list controls, such as the CheckBoxList
and RadioButtonList
controls, allowing for easy programmatic interaction with the control. These controls can also be bound to a database, allowing you 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 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 react when the user clicks 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
, and 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; we’ll learn more about many of them (as well as others that aren’t covered in this chapter) as we progress through this book.
Calendar
The Calendar
is a great example of the reusable nature of ASP.NET controls. The Calendar
control generate the markup to display 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, and can be created within a page like this:
Example 4.4. Calendar.aspx (excerpt)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Calendar Test</title>
</head>
<body>
<form runat="server">
<asp:Calendar id="myCalendar" runat="server" />
</form>
</body>
</html>
If you save this page in the Learning
folder and load it, you’d get the output shown in Figure 4.4.
Figure 4.4. Displaying the default calendar
The Calendar control contains a wide range of properties, methods, and events, including those listed here:
DayNameFormat
– This property sets the format of the day names. Its possible values areFirstLetter
,FirstTwoLetters
,Full
, andShort
. The default isShort
, which displays the three-letter abbreviation.FirstDayOfWeek
– This property sets the day of the week 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 Sunday or Monday if you want to control it.NextPrevFormat
– Set toCustomText
by default, this property can be set toShortMonth
orFullMonth
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 a lot to determine which day the user has selected.SelectionMode
– This property determines whether days, weeks, or months can be selected; its possible values areDay
,DayWeek
,DayWeekMonth
, andNone
, and the default isDay
. WhenDay
is selected, a user can only select a day; whenDayWeek
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
– IfTrue
, this property displays the names of the days of the week. The default isTrue
.ShowGridLines
– IfTrue
, this property renders the calendar with grid lines. The default isTrue
.ShowNextPrevMonth
– IfTrue
, this property displays next/previous month links. The default isTrue
.ShowTitle
– IfTrue
, this property displays the calendar’s title. The default isFalse
.TitleFormat
– This property determines how the month name appears in the title bar. Possible values areMonth
andMonthYear
. The default isMonthYear
.TodaysDate
– ThisDateTime
value sets the calendar’s current date. By default, this value is not highlighted within theCalendar
control.VisibleDate
– ThisDateTime
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 that allows users to select days, weeks, and months. Modify the calendar in Calendar.aspx
, and add a label to it, as follows:
Example 4.5. Calendar.aspx (excerpt)
<asp:Calendar ID="myCalendar" runat="server" DayNameFormat="Short"
FirstDayOfWeek="Sunday" NextPrevFormat="FullMonth"
SelectionMode="DayWeekMonth" SelectWeekText="Select Week"
SelectMonthText="Select Month" TitleFormat="Month"
OnSelectionChanged="SelectionChanged" />
<h2>You selected these dates:</h2>
<asp:Label ID="myLabel" runat="server" />
Now add a <script runat="server">
tag to the head of the web form to include the SelectionChanged
event handler referenced by your calendar:
Example 4.6. Calendar.aspx (excerpt)
<script runat="server" language="VB">
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>
Example 4.7. Calendar.aspx (excerpt)
<script runat="server" language="C#">
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 similar to this display shown in Figure 4.5.
Figure 4.5. Using the Calendar control
In SelectionChanged
, we loop through each date that the user has selected, and append it to the BulletedList
we added to the page.
AdRotator
The AdRotator
control allows you to display a list of banner advertisements within your web application at random. 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. As most of the AdRotator
control’s properties reside within an XML file, if you wished, you could share that XML file on the Web, essentially allowing value added resellers (VARS), or possibly your companies’ partners, to use your banner advertisements on their web sites.
XML Basics
In essence, XML is simply a text-based format for the transfer or storage of data; it contains no details on 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 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:
<p>Star Wars Episode I: The Phantom Menace</p>
This example describes the content between the tags as a paragraph. This is fine if all we are concerned with is displaying the words "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 unlike HTML, XML doesn’t describe how that content should be displayed; it describes 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 out, create a file called ads.xml in your Learning folder, 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.
Example 4.8. Ads.xml (excerpt)
<Advertisements>
<Ad>
<ImageUrl>workatdorknozzle.gif</ImageUrl>
<NavigateUrl>http://www.dorknozzle.com</NavigateUrl>
<TargetUrl>_blank</TargetUrl>
<AlternateText>Work at Dorknozzle.com!</AlternateText>
<Keyword>HR Sites</Keyword>
<Impressions>2</Impressions>
</Ad>
<Ad>
<ImageUrl>getthenewsletter.gif</ImageUrl>
<NavigateUrl>http://www.dorknozzle.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 adNavigateURL
– the web page to which your users will navigate when they click the banner adAlternateText
– the alternative text to display for browsers that do not support imagesKeyword
– the keyword to use to categorize your banner ad. If you use theKeywordFilter
property of theAdRotator
control, you can specify the categories of banner ads to display.Impressions
– the relative frequency that 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
, with the following code:
Example 4.9. AdRotator.aspx (excerpt)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>AdRotator Control</title>
</head>
<body>
<form runat="server">
<asp:AdRotator ID="adRotator" runat="server"
AdvertisementFile="Ads.xml" />
</form>
</body>
</html>
You’ll need to download workatdorknozzle.gif
and getthenewsletter.gif
and place them in the Learning
folder in order to see these ad images. Save your work and test it in the browser; the display should look something like Figure 4.6.
Figure 4.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. You’ll learn 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
located in the root of your project. The Web.sitemap
file is an XML file that looks like this:
Example 4.10. Web.sitemap
<siteMap
xmlns="http://schemas.microsoft.com/AspNet/net/codeguru-sitemap/-File-1.0">
<siteMapNode title="Home" url="~/Default.aspx"
description="Home">
<siteMapNode title="TreeViewDemo" url="~/TreeViewDemo.aspx"
description="TreeView Example" />
<siteMapNode title="ClickEvent" url="~/ClickEvent.aspx"
description="ClickEvent Example" />
<siteMapNode title="Loops" url="~/Loops.aspx"
description="Loops Example" />
</net/codeguru-sitemap/Node>
</net/codeguru-sitemap/>
Web.sitemap
Limitation
An important limitation to note when 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 siteMapNode
alongside (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:
Example 4.11. TreeViewDemo.aspx (excerpt)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>TreeView Demo</title>
</head>
<body>
<form runat="server">
<asp:SiteMapDataSource ID="mySiteMapDataSource"
runat="server" />
<asp:TreeView ID="myTreeView" runat="server"
DataSourceID="mySiteMapDataSource" />
</form>
</body>
</html>
Note that although the SiteMapDataSource
is a control, it does not generate any HTML within the web page. There are many data source controls like this; we’ll delve into this in more detail later.
When combined with the example Web.sitemap
file above, this web form would generate an output such as that shown in Figure 4.7.
Figure 4.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 don’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 provide handy links to the current location’s ancestor nodes. An example of a breadcrumb navigation system is shown in Figure 4.8.
Figure 4.8. A breadcrumb created using the SiteMapPath
control
The SiteMapPath
control will automatically use any SiteMapDataSource
control that exists in a web form to display a user’s current location within the site. For example, you could simply add the following code to the form we worked with in the previous example to achieve the effect shown in Figure 4.8:
Example 4.12. TreeViewDemo.aspx (excerpt)
<asp:SiteMapPath id="mySiteMapPath" runat="server"
PathSeparator=" > ">
</asp:SiteMapPath>
If you run the example now, you’ll see the breadcrumb appear exactly as it’s shown in Figure 4.8.
Note that the SiteMapPath
control shows only the nodes that correspond to existing pages of your site, so if you don’t have a file named Default.aspx
, the root node link won’t show up. Similarly, if the page you’re loading isn’t named TreeViewDemo.aspx
, the SiteMapPath
control won’t generate any output.
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 and submenu items).
MultiView
The MultiView
control is similar to Panel in that it doesn’t generate interface elements itself, but contains other controls. 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 being presented to the visitor) by setting the value of the ActiveViewIndex
property. The first page corresponds to an ActiveViewIndex
of 0
, the second page is 1
, the third page is 2
, and so on.
The contents of each template are defined inside child View
elements. Consider the following code snippet, which creates a Button
control, and a MultiView
control:
Example 4.13. MultiViewDemo.aspx (excerpt)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>MultiView Demo</title>
</head>
<body>
<form runat="server">
<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>
</form>
</body>
</html>
As you can see, by default, the ActiveViewIndex
is 0
, so when this code is first executed, the MultiView
will display its first template, shown in Figure 4.9.
Figure 4.9. Using the MultiView
control
Clicking on the button will cause the second template to be displayed. Here’s the code for the SwitchPage
event handler:
Example 4.14. MultiViewDemo.aspx (excerpt)
<script runat="server" language="VB">
Sub SwitchPage(s as Object, e as EventArgs)
myMultiView.ActiveViewIndex = _
(myMultiView.ActiveViewIndex + 1) Mod 2
End Sub
</script>
Example 4.15. MultiViewDemo.aspx (excerpt)
<script runat="server" language="C#">
public void SwitchPage(Object s, EventArgs e)
{
myMultiView.ActiveViewIndex =
(myMultiView.ActiveViewIndex + 1) % 2;
}
</script>
This simple subroutine uses the modulo operator to set the ActiveViewIndex
to 1
when its original value is 0
, and vice versa.
The MultiView
controls 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’s able to 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. You’ll learn how to use this control in Chapter 14, Working with Files and Email.
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 4.10.
Figure 4.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.
In your Learning
folder, create a new file named SmartBox.ascx
. Then, add the control’s constituent controls–a Label
control and a TextBox
control–as shown below:
Example 4.16. SmartBox.ascx (excerpt)
<p>
<asp:Label ID="myLabel" runat="server" Text="" Width="100" />
<asp:TextBox ID="myTextBox" runat="server" Text="" Width="200"
MaxLength="20" />
</p>
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, you should use a CSS style sheet and the CssClass
property, which we’ll take a look at later in this chapter.
In Chapter 3, VB and C# Programming Basics, we discussed properties briefly, but we didn’t explain how you could create your own properties within your own classes. So far, you’ve worked with many properties of the built-in controls. For example, you’ve seen a lot of code that sets the Text
property of the Label
control.
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 typed by the user in 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
:
Example 4.17. SmartBox.ascx (excerpt)
<script runat="server" language="VB">
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>
Example 4.18. SmartBox.ascx (excerpt)
<script runat="server" language="C#">
public string LabelText
{
set
{
myLabel.Text = value;
}
}
public string Text
{
get
{
return myTextBox.Text;
}
}
</script>
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 here. You’ll meet more complex web user controls in the chapters that follow.
When you use the SmartBox
control in a form, you can set its label and have the text entered by the user, like this:
mySmartBox.LabelText = "Address:"
userAddress = mySmartBox.Text
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 read and write, 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, that action sets the Text
property of our Label
control, as shown below:
Example 4.19. SmartBox.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:
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
; this 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
:
Example 4.20. SmartBox.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 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:
Example 4.21. SmartBox.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:
Example 4.22. SmartBox.ascx (excerpt)
public string LabelText
{
set
{
myLabel.Text = value;
}
}
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 conflictsTagName
– the control’s tag name, which will be used when the control is added to the ASP.NET pageSrc
– the path to the.ascx
file that describes the user control
After registering the control, we create instances of it using the <TagPrefix:TagName>
format. Let’s try an example that uses the SmartBox
control. Create a new file named ControlTest.aspx
in your Learning
folder, and give it this content:
Example 4.23. ControlTest.aspx (excerpt)
<%@ Register TagPrefix="sp" TagName="SmartBox"
Src="SmartBox.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Creating ASP.NET Web Server Controls</title>
</head>
<body>
<form id="Form1" runat="server">
<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:" />
</form>
</body>
</html>
Loading this page will produce the output we saw in Figure 4.10.
Now, this is a very simple example indeed, but we can easily extend it for other purposes. You can see in the code snippet that we set the LabelText
property directly in the control’s tag; we could have accessed the properties from our code instead. Here’s an example:
Example 4.24. ControlTest.aspx (excerpt)
<script runat="server" language="VB">
Protected Sub Page_Load()
nameSb.LabelText = "Name:"
addressSb.LabelText = "Address:"
countrySb.LabelText = "Country:"
phoneSb.LabelText = "Phone:"
End Sub
</script>
Example 4.25. ControlTest.aspx (excerpt)
<script runat="server" language="C#">
protected void Page_Load()
{
nameSb.LabelText = "Name:";
addressSb.LabelText = "Address:";
countrySb.LabelText = "Country:";
phoneSb.LabelText = "Phone:";
}
</script>
Master Pages
Master pages are a new feature of ASP.NET 2.0 that can make an important difference in the way we compose web forms. Master pages are similar to web user controls in that they are also 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 easily modify and extend the site. If your site uses these features in a well-planned way, it can be very easy to modify certain details in the layout or functionality of your site, because updating a master page or a web user control has immediate effects 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 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 which has many pages that contain a standard header, footer, and navigation menu, laid out as per the wireframe shown in Figure 4.11.
Figure 4.11. 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. We’ll begin to create such a site in Chapter 5, Building Web Applications, but let’s work through a quick example here.
To keep this example simple, we won’t include a menu here: we’ll include just the header, the footer, and the content placeholder. In your Learning
folder, create a new file named FrontPages.master
, and write the following code into it:
Example 4.26. FrontPages.master (excerpt)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Front Page</title>
</head>
<body>
<form id="myForm" runat="server">
<h1>Welcome to SuperSite Inc!</h1>
<asp:ContentPlaceHolder id="FrontPageContent"
runat="server" />
<p>Copyright 2006</p>
</form>
</body>
</html>
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 called FrontPage.aspx
, and add this code to it:
Example 4.27. FrontPage.aspx (excerpt)
<%@ Page MasterPageFile="FrontPages.master" %>
<asp:Content id="myContent" runat="server"
ContentPlaceHolderID="FrontPageContent">
<p>
Welcome to our web site! We hope you'll enjoy your visit.
</p>
</asp:Content>
You’re all set now! Loading FrontPage.aspx
in your browser will generate the output shown in Figure 4.12.
Figure 4.12. Using a master page
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, the master page can define some default content for display inside the ContentPlaceHolder
on pages whose web forms don’t provide a Content
element for that placeholder.
Using Cascading Style Sheets (CSS)
It’s clear that controls make it easy for us to reuse pieces of functionality in multiple places. For example, I can’t imagine an easier way to add calendars to many web forms than to use the Calendar
web server control.
However, controls don’t solve the problem of defining and managing the visual elements of your web site. Modern web sites need constant updating to keep them fresh, and it’s not much fun editing hundreds of pages by hand just to change a border color, for example, and then having to check everything to ensure that the changes are consistent. The process is even more painful if the client wants a more serious update, like rearranging components on the pages.
The good news is that this maintenance work can be made a lot easier by planning ahead, correctly following a few basic rules, and efficiently using the tools HTML and ASP.NET offer you.
An essential tool for building reusable visual styles is CSS (Cascading Style Sheets). HTML was initially designed to deliver simple text content, and paid little attention to the specifics of how particular items appeared in the browser. HTML left it to the individual browsers to work out these intricacies, and tailor the output to the limitations and strengths of users’ machines. While we can change font styles, sizes, colors, and so on using HTML tags, this practice can lead to verbose code and pages that are very hard to restyle at a later date.
CSS gives web developers the power to create one set of styles in a single location, and to apply those styles to all of the pages in our web site. All the pages to which the style sheet is applied will display the same fonts, colors, and sizes, giving the site a consistent feel. Regardless of whether our site contains three pages or 300, when we alter the styles in the style sheet, our changes are immediately applied to all pages that use the style sheet.
Look out for Themes and Skins
ASP.NET 2.0 provides extra value and power to those building reusable visual elements through its offerings of themes and skins. You’ll learn more about these features in Chapter 5, Building Web Applications.
Types of Styles and Style Sheets
There are three different ways in which we can associate styles to the elements of a particular web page:
1. Using an external style sheet
By placing your style rules in an external style sheet, you can link this one file to any web pages on which you want those styles to be used. This makes updating a web site’s overall look a cakewalk.
To reference an external style sheet from a web form, insert the following markup inside the head element:
<link rel="stylesheet" type="text/css" href="file.css" />
In the above example, file.css
would be a text file containing CSS rules, much like the example shown below:
a
{
background: #ff9;
color: #00f;
text-decoration: underline;
}
2. Using an embedded style sheet
You can place style rules for a page within <style type="text/css">
tags inside that page’s head
.
<style type="text/css">
a
{
background: #ff9;
color: #00f;
text-decoration: underline;
}
</style>
The problem with using these "embedded" styles is that we can’t reuse those styles in another page without having to type them in again, which makes global changes to the site very difficult to manage.
3. Using inline style rules
Inline styles allow us to set styles for a single element using the style attribute. For instance, we might give a paragraph a border, and color it red, with the following markup:
<p style="border-style: groove; color: red;">
Copyright 2006
</p>
When used in embedded or external style sheets, the first part of any style rule must determine the elements to which the rule will apply; we do this using a selector. In ASP.NET, we typically use two types of selectors:
1. element type selectors
An element type selector targets every single instance of the specified element. For example, if we wanted to change the colour of all level two headers in a document, we’d use an element type selector to target all <h2>
s:
h2
{
color: #369;
}
2. classes
Arguably the most popular way to use styles within your pages is to give each element a class
attribute, then target elements that have a certain class value. For example, the following markup shows a paragraph whose class
attribute is set to fineprint
:
<p class="fineprint">
Copyright 2006
</p>
Now, given that anything with the class fineprint
should be displayed in, well, fine print, we can create a style rule that will reduce the size of the text in this paragraph, and any other element with the attribute class="fineprint"
:
.fineprint
{
font-family: Arial;
font-size: x-small;
}
Whether you’re building external style sheets, embedded style sheets, or inline style rules, style declarations use the same syntax.
Now that you have a basic understanding of some of the fundamental concepts behind CSS, let’s look at the different types of styles that can be used within our ASP.NET applications.
Style Properties
You can modify many different types of properties using style sheets. Here’s a list of the most common property types:
font
– This category provides you with the ability to format text level elements, including their font faces, sizes, decorations, weights, colors, etc.background
– This category allows you to customize backgrounds for objects and text. These values give you control over the background, including whether you’d like to use a color or an image for the background, and whether or not you want to repeat a background image.block
– This category allows you to modify the spacing between paragraphs, between lines of text, between words, and between letters.box
– Thebox
category allows us to customize tables. If you need to modify borders, padding, spacing, and colors on a table, row, or cell, use the elements within this category.border
– This category lets you draw boxes of different colors, styles, and thicknesses around page elements.list
– This category allows you to customize the way ordered and unordered lists are created.positioning
– Modifying positioning allows you to move and position tags and controls freely.
These categories provide an outline of the aspects of a design that can typically be modified using CSS. As we progress through the book, the many types of style properties will become evident.
The CssClass
Property
Once you’ve defined a class in a style sheet (be it external or internal), you’ll want to begin to associate that class with elements in your Web Forms. You can associate classes with ASP.NET Web server controls using the CssClass
property. In most cases, the value you give the CssClass
property will be used as the value of the resulting element’s class attribute.
Let’s see an example. First, create in your Learning folder a file named Styles.css
, and copy this code into it:
Example 4.28. Styles.css
.title
{
font-family: Arial, Helvetica, sans-serif;
font-size: 19px
}
.dropdownmenu
{
font-family: Arial;
background-color: #0099FF;
}
.textbox
{
font-family: Arial;
background-color: #0099FF;
border: 1px solid
}
.button
{
font-family: Arial;
background-color: #0099FF;
border: 1px solid
}
Then, create a new file named UsingStyles.aspx
with this code:
Example 4.29. UsingStyles.aspx (excerpt)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Testing CSS</title>
<link href="Styles.css" type="text/css" rel="stylesheet" />
</head>
<body>
<form runat="server">
<p class="title">Please select a product:</p>
<p>
<asp:DropDownList id="productsList"
CssClass="dropdownmenu" runat="server">
<asp:ListItem Text="Shirt" selected="true" />
<asp:ListItem Text="Hat" />
<asp:Listitem Text="Pants" />
<asp:ListItem Text="Socks" />
</asp:DropDownList>
</p>
<p>
<asp:TextBox id="quantityTextBox" CssClass="textbox"
runat="server" />
</p>
<p>
<asp:Button id="addToCartButton" CssClass="button"
Text="Add To Cart" runat="server" />
</p>
</form>
</body>
</html>
Loading this page should produce the output shown in Figure 4.13.
Figure 4.13. CSS at work
In the next chapter, we’ll learn to use Visual Web Developer to create CSS definitions through a simple visual interface.
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’ll 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.