Tải bản đầy đủ (.pdf) (90 trang)

Beginning ASP.NET 1.1 with Visual C# .NET 2003 phần 6 ppt

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.68 MB, 90 trang )


{
Session["SelectedCss"] = "WroxUnited.css";
}
else
{
Session["SelectedCss"] = Request.Cookies["PreferredCss"].Value;
}
}
}

That's quite a lot of Ifs! Don't worry – we will come to this in just a moment. However, before
you can run the code, you need to include some stylesheets or nothing will be displayed! You
will also need to make some minor adjustments to some of the code on the page, notably to the
Calendar control's DayRender event handler, to make the page look a bit nicer when the
stylesheet is applied.
6. First, change the DayRender event handler as follows (remove the original style settings and
replace them with a single class statement):
public void EventCalendar_DayRender(object sender, DayRenderEventArgs e)
{
if (((Hashtable)Cache["DateList"])[e.Day.Date] != null)
{
e.Cell.CssClass = "selecteddate";
// e.Cell.Style.Add("font-weight", "bold");
// e.Cell.Style.Add("font-size", "larger");
// e.Cell.Style.Add("border", "3 dotted darkred");
// e.Cell.Style.Add("background", "#f0f0f0");
// The following line will exist in your code if you completed the
// exercises at the end of the last chapter
e.Day.IsSelectable = true;
}


else
{
// This line of code is part of the solution to one of the exercises at
// the end of chapter 10
e.Day.IsSelectable = false;
e.Cell.CssClass = "normaldate";
// e.Cell.Style.Add("font-weight", "lighter")
// e.Cell.Style.Add("color", "DimGray")
}
}
7. Change the code for the calendar in the HTML view:
<asp:Calendar id="EventCalendar" runat="server"
OnSelectionChanged="EventCalendar_SelectionChanged"
OnDayRender="EventCalendar_DayRender" CssClass="calendar">
<DayStyle cssclass="normaldate"></DayStyle>
<OtherMonthDayStyle cssclass="othermonthdate"></OtherMonthDayStyle>
423
Users and Applications
</asp:Calendar>
8. Now create a new blank stylesheet, and call it WroxUnited.css, as shown in Figure 11-18:
Figure 11-18
9. In this new stylesheet, enter the following code:
BODY {
{
background-image:url(images/background.gif);
color:"#000000";
font-family: georgia;
}
a {
color:"#8b0000";

font-weight:bold;
}
.selecteddate{
font-weight: bold;
font-size: larger;
border: 3 dotted darkred;
background:#f0f0f0;
}
.normaldate{
font-weight:lighter;
color:dimgray;
}
.calendar a{
text-decoration:none;
font-size: 10pt;
}
424
Chapter 11
.othermonthdate{
font-weight:lighter;
color:#d3d3d3;
}
10. Save this as WroxUnited.css in the WroxUnited folder. Then, change the following lines and
save the file with a different name,
WroxUnited2.css:
BODY {
background-image:url(images/awaybackground.gif);
color:"#ffffff";
font-family: georgia;
}

a {
color:"yellow";
font-weight:bold;
}
.calendar a{
text-decoration:none;
}
.selecteddate
{
font-weight: bold;
font-size: larger;
border: 3 dotted white;
background:#c0c0c0;
}
.normaldate
{
font-weight:lighter;
color:#d3d3d3;
}
.othermonthdate
{
font-weight:lighter;
color:dimgray;
}
11. Finally, you need to get hold of the two background images that are used in the two stylesheets,
background.gif and awaybackground.gif. Both are available for download from the Wrox
site. They are extremely small images, so they will not take long to download.
12. It's about time to run the page and try it out for yourself! The first style you'll see is the Home
style page, as shown in Figure 11-19, the away kit that is shown in Figure 11-20, is fairly
different, as you’ll no doubt notice!

425
Users and Applications
Figure 11-19:
Figure 11-20
426
Chapter 11
13. If you check the Remember Preference box before clicking Apply, the style you are applying will
be remembered for you in a cookie. Next time you open the site, this stylesheet will be the
default.
How It Works
This example rolled together two different techniques, sessions and cookies, and gave a unified look and
feel that you can apply to all the pages in this site.
The first thing done was to use the contents of the
Session object to provide a filename for the <Link
>
tag in the head section of the ASP.NET page:
<html>
<head>
<link id="css" href='<%= (string)Session["SelectedCss"] %>'
type="text/css"
rel="stylesheet" />
</head>
You'll recall that the <%= %> syntax is used to access ASP.NET objects from the HTML side of the
page. This technique is certainly adequate for this example, and is a simple way to get to the contents of
the
Session object.
The next step was to add some controls to the page to select and apply the stylesheet to the page:
<hr /><br/><br/>
<p>
Choose a theme: <br/>

<asp:DropDownList id="ddlTheme" runat="server">
<asp:ListItem Value="WroxUnited.css" Selected="true">
Home Kit</asp:ListItem>
<asp:ListItem Value="WroxUnited2.css">Away Kit</asp:ListItem>
</asp:DropDownList>
<asp:Button id="btnApplyTheme" onclick="btnApplyTheme_Click"
runat="server" Text="Apply"></asp:Button>
<br />
<asp:CheckBox id="chkRememberStylePref" runat="server"
Text="Remember preference"></asp:CheckBox>
</p>
We set the details of the drop down list manually, assigning each item a Text property and a Value
property. The Text property (the bit between the tags) is the text that displays in the control. The value
is the underlying code value for the selected item, and we use this value to update the session. Clicking
the
Apply button will fire the Click event of the button, taking you neatly to the event handler for this
event:
void btnApplyTheme_Click(object sender, EventArgs e)
{
Session["SelectedCss"] = ddlTheme.SelectedItem.Value;
Set the value of the session to be the value of the currently selected drop down list item (not the
displayed text). This value is the filename for the stylesheet.
427
Users and Applications
if (chkRememberStylePref.Checked)
{
HttpCookie CssCookie = new HttpCookie("PreferredCss");
CssCookie.Value = ddlTheme.SelectedItem.Value;
CssCookie.Expires = DateTime.Now.AddSeconds(20);
Response.Cookies.Add(CssCookie);

}
}
If the ChkRememberStylePref checkbox is checked when the button is clicked, a cookie is added to the
user's machine, specifying their preference for subsequent visits to the site. Again, we set a short expiry
time for this cookie so that you can see it working and also see what happens when it expires. You can
set this to be whatever time interval you prefer.
OK, so you have a session and a cookie – the next stage is to read those values in when the page is
loaded:
public void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["SelectedCss"] == null)
{
If the Session does not yet exist, we set a default value for the selected stylesheet using the value in the
cookie if one exists on the client machine, or set it to a specific value if there is no cookie present:
if (Request.Cookies["PreferredCss"] == null)
{
Session["SelectedCss"] = "WroxUnited.css";
}
else
{
Session["SelectedCss"] = Request.Cookies["PreferredCss"].Value;
}
}
}
Now that we have applied the stylesheet, we need to manually alter the styling of the Calendar control
(if you skip this step, you'll notice that the calendar doesn't follow the stylesheet like the rest of the
page):
public void EventCalendar_DayRender(object sender, DayRenderEventArgs e)

{
if (((Hashtable)Cache["DateList"])[e.Day.Date] != null)
{
e.Cell.CssClass = "selecteddate";
e.Day.IsSelectable = true;
}
else
{
e.Day.IsSelectable = false;
e.Cell.CssClass = "normaldate";
428
Chapter 11
}
}

<DayStyle cssclass="normaldate"></DayStyle>
<OtherMonthDayStyle cssclass="othermonthdate"></OtherMonthDayStyle>
Finally, we declare some stylesheet information. Let's run through the values of just a couple of these
definitions:
BODY {
background-image:url(images/background.gif);
color:"#000000";
font-family: georgia;
}
The BODY tag controls the way the bulk of the page is rendered, including any background coloring or
styling, as well as the font color and style.
The
.selecteddate style is the style added in the DayRender() event handler for the calendar:
.selecteddate{
font-weight: bold;

font-size: larger;
border: 3 dotted darkred;
background:#f0f0f0;
}
Notice how the styles here are similar to the styles used in the code for the DayRender() event handler
previously? Well, that's the joy of stylesheets! You've now centralized this code so that you only have to
alter it in one place.
Summary
We covered quite a bit of ground in this chapter. We used cookies, sessions, and applications and cached
data for enhancing performance. We also had some fun with interactive examples in this chapter that
demonstrated these concepts.
The important points covered in this chapter are:
❑ Cookies are a neat way to store small pieces of identifying data, but cannot be relied upon (users
may have them disabled in their browser preferences).
❑ Sessions are an extremely powerful way to store data that exists for as long as a user is
connected to the site, and you can use them to store data for online shopping examples.
❑ Application-scope objects are accessible by any page in an application and are a great way to
centralize objects that need to be shared.
❑ Caching data is crucial to improving application performance, but it's also similar to storing
data in the
Application object. However, the Cache object has some neat features such as
429
Users and Applications
linking to a dependency, and you can control when items in the cache expire and react to the
events raised when those items expire.
The next chapter will look at encapsulating commonly used page elements into reusable sections known
as user controls. You'll also learn how the code-behind technique can be used to cleanly separate HTML
code from C# code.
Exercises
1. Add the text, Current Topic, and a label control to the Chat.aspx page above the main chat box

that contains the text of the current topic (stored in the
Application object). Add some default
topic text to the
Global.asax file, and also another box and button to the page, allowing you to
change the current topic.
2. Add the session initialization code from the Stylesheet example to your Global.asax file.
3. Add a link to the Merchandise.aspx page from the front page of the site, then apply the
stylesheet used in the
Default.aspx page to all the other pages in the site. You will need to
add the
<link > tag to the <head > section of each page, and you will need to ensure
that the session initialization code is correctly configured in the
Global.asax file from the
previous exercises.
430
Chapter 11
12
Reusable Code for ASP.NET
So far, most of the ASP.NET pages we've built were quite specialized and self-contained. We've put
a lot of functionality into each page, but only retained the benefits of our hard work from one page
to another by copying the entire contents into a new ASPX page.
This isn't an ideal way to write functionality-rich Web sites, particularly if you're on a salary and
expected to deliver results before the next millennium! We'll now look at writing reusable code for
ASP.NET. Note that we're not just talking about objects here (although, yet again, objects play a
crucial role in the reusability story), but about code components – totally independent files that
encapsulate groups of useful functionality.
This chapter will look at two specific ways of using components in ASP.NET:

User control: A Web form that is encapsulated in a reusable server control


Code-behind: Used for separating HTML user interface design (color, aesthetics, and so
on) from page code
First, let's take a careful look at what is meant by components and consider the various advantages
they offer.
Encapsulation
As discussed in Chapter 7, an object essentially is a software construct that bundles together data
and functionality. You can define interfaces to use the functionality that an object contains, for
example, by creating methods and properties that can be accessed programmatically.
By hiding everything that doesn't concern task-specific usage of an object, implementation details
are hidden from the consumer, which makes it a lot easier to robustly plug an object together with
other objects. This makes it far easier for large teams of developers to build complex applications
that don't fall prey to lots of low-level weaknesses.
Crucial information about an object is held in its class definition, and any code with access to this class
should be able to instantiate an instance of this class and store it in an object. The way in which the
object works is encapsulated, so that only the public methods and properties are available to the
consumers of the class.
In a similar way, a code component is reusable code stored in a location that is accessible to many
applications. Like an object, it encapsulates functionality, but while an object is an implementation unit,
a component is a deployment or packaging unit. A component could be a single class or could hold
multiple class definitions. Figure 12-1 considers a quick example:
Figure 12-1
The first ASP.NET page creates a new object of type Class1 that resides within the Component1
component. The second ASP.NET page creates two new objects – one of type Class1 and one of type
Class2. Class2 also resides within Component1.
All code written so far has been held in specific ASPX pages. So, what's the point in having all this
reusable code if it can only be reached from within a single page? We need to break our reusable code
into separate components that we can reference from other ASPX pages.
A component packages a set of classes and interfaces to isolate and encapsulate a specific functionality,
and can provide a well-specified set of publicly available services. It is designed for a specific purpose
rather than for a specific application.

Components
A component is a self-contained unit of functionality with external interfaces that are independent of its
internal architecture. In other words, it is code packaged as a black box that can be used in as many
different applications as required.
432
Chapter 12
Microsoft Windows is an example of componentization. If you spend a lot of time working with
Windows, you're almost certain to have come across Dynamic Link Libraries (DLL) files. These files
contain components that define most of the functionality that you're likely to come across in Windows,
including that of any applications you've installed.
For example, every time you start an instance of Internet Explorer, you're actually running a small
program called
iexplore.exe. This program accesses numerous DLLs that reside in your system
directory (
C:\WinNT or C:\Windows), and most of the browser's functionality is defined within these
files. This directory also contains the
Explorer.exe file, which is the executable for Windows Explorer.
Note that both these applications feature an identical
Address bar, where you type in the URL of a Web
site or the path to a local directory. This user interface element has been implemented once and
packaged inside a component, so that it can now be used by both programs.
What's more, if you enter the URL for a Web page in the Windows Explorer address bar, you can view
that page and even browse the Web in the main pane without having to use
iexplore.exe at all.
Likewise, you can use
iexplore.exe to view and browse your files by entering a file path in the
address bar.
What we can deduce from this is that either there's a lot of duplication between the two executable files,
or that the two sets of browser functionality are actually implemented as standalone components that
can be accessed by both applications.

Another case to consider is the Microsoft Office suite, which features many components that are shared
among individual Office applications, as also throughout Windows. For example, there is a component
that handles the
Save As dialog used by Word, Excel, Outlook, and the rest – this is why the Save As
dialog looks the same, no matter which application you run it from. This component is actually a
Windows component and the Office package uses it whenever you save or load a file. You can also use
this from any other application that lets you save or load files, for example, Internet Explorer or even
Microsoft Notepad as shown in Figure 12-2:
Figure 12-2
433
Reusable Code for ASP.NET
This component probably includes some presentation code for the buttons and code logic that governs
what happens when you click on each of these buttons. For example, changing the selection in the Save
option in dropdown box changes the files listed in the main window to show the contents of the selected
directory.
Throughout this book, the
aspnet_isapi component has been working away behind IIS to process all
of our ASP.NET pages. When IIS detects a request for a page with a
.aspx extension, it uses this
component to process the page and communicate with the .NET Framework.
DLLs are classified as system files and are hidden by default. They can only be seen in Windows
Explorer if the 'Show hidden files and folders' option in your
Folder Options
is set. The DLLs talked
about in these examples are COM DLLs. .NET DLLs differ slightly in what they contain and the
underlying technology, but the concept of componentization used is the same.
Why Use Components?
You should start thinking of components as small, self-contained nuggets of functionality that can
potentially make life a lot simpler when building any sort of non-trivial application. In components,
behind-the-scenes functionality is encapsulated so that only certain specific interfaces are available to the

programmer. It can contain class definitions that specify which objects can be created and which ones
can be used for behind-the-scenes code. The benefits of using components include:
❑ An individual component is a lot simpler than a fully-blown application. It is restricted to a set
of predefined functionality.
❑ As components are self-contained, they can be seamlessly upgraded (or fixed) simply by
replacing one component with another that supports the same interfaces (methods, properties,
and so on).
❑ Since using components is a good way of dividing your application into serviceable chunks,
sometimes the functionality of a component might be reusable in other applications. You could
even make it available to other programmers, or incorporate some of their components into
your applications.
Ultimately, components reduce the amount of code you write and make your code easier to maintain.
Moreover, you can even obtain components from third party component vendors, which is a very
popular way to enhance the functionality of ASP.NET sites. For example, if you need components that
utilize the drawing capabilities of .NET to their limit, and your existing knowledge does not cover this,
you can consider looking for a third-party solution that you can bolt onto your application.
Applying Component Theory to Applications
Let's look at how componentization relates to our application models. So far in this book, we've made
ASP.NET pages that do all sorts of things ranging from working with information input via a form to
connecting to a database and working with data. Throughout the book, you've been encouraged to keep
your code separated into distinct blocks – the dynamically generated content (ASP.NET code) and
presentation (HTML and various controls) – so that it's easy to change the look of your page without
affecting what it does. Web Matrix simplifies this process with its separate
HTML and Code views.
434
Chapter 12
In addition, we've written a lot of C# code in our pages for accessing and working with data stored in a
central database. C# provides a framework of logical operations between the data and presentation code.
Let's consider an example. Imagine a team of developers creating a Web site that sells books. Some of
these developers would be concerned with the look, feel, and usability of the site. They'd be responsible

for the public image of the company on the Web, so they'd be more concerned about design, color, and
usability. This group will include designers who probably use HTML and graphics tools such as
Macromedia Flash for fancy loading screens. Another set of developers would be mainly interested in
providing nifty blocks of code that do cool things, such as such as validating the information entered
into a form by the customers when they click a button. These developers would also be responsible for
generating the code required to connect to the database of different books and preparing information on
individual titles for display on the site. The designers would then make use of that information and
display it in an aesthetically pleasing fashion.
If you were to constantly use ASP.NET pages that had all of the code and HTML on the same page, it
would be awkward for both sets of people to work on the site at once. Simple mistakes could easily be
made if people overwrote each other's code. In addition, every page would have to be hand-made, and
code would have to be copied, pasted, and amended as appropriate. If you made one change to the
functionality of your site, you'd have to remember to make that change to all the appropriate pages.
However, if you could separate out the HTML and design-focused code from the ASP.NET code blocks,
and then reuse bits of that code, it would be much easier to update a single piece of code to change
functionality – every page that used it would be automatically updated.
This style of work would make everyone happy – Web designers get to play with color and layout as
much as they like, and the ASP.NET developers can fine-tune their code without affecting the look and
feel of the site. Code separation and reuse implies that the designers and developers can work in
parallel, allowing applications to be developed much more quickly. This is called Rapid Application
Development.
This chapter will look at two ways of dividing code into reusable sections – user controls and code-behind
files. In the next chapter, we'll take this one step further and look at compiled components and custom
server controls.
Let's look at user controls, the first application of this code-separation concept.
User Controls
When the ASP.NET team first devised the concept of user controls, they were called pagelets, a term that
many people disliked. They were later renamed, but many felt that pagelet, or a mini-page, was a good
descriptive term for these controls.
User controls are Web forms encapsulated into a reusable control. They hold blocks of code that are

repetitively required by many pages in a Web site. For example, consider the Microsoft Web site where
each page has the same header style – a menu bar and a logo. This is a common feature for many Web
sites; our own
shown in Figure 12-3 has this kind of style, for example:
435
Reusable Code for ASP.NET
Figure 12-3
The Wrox site has the same kinds of menu bars visible on the screen at all times. These panes, panels, or
frames (depending on what you call them and how you code them) form just one example of what user
controls can provide.
Instead of having to copy and paste chunks of repeated code to provide the header on all of our pages,
we can create a simple user control that will have this code inside it, ready to be used. It's a way of
accessing the same functionality repeatedly throughout an application.
If you've ever programmed with ASP 3.0, you'll probably be familiar with include files. User controls
are similar to these files, but because ASP.NET is different from ASP 3.0, these controls are now created
and used in a different manner, and include advanced features such as caching (covered in Chapter 11).
User controls can also do a lot more than simply produce headers and footers. We can give these controls
the ability to look and function like ASP.NET Server controls. We can code properties so that the control
can adapt according to its set attributes. A user control can be used repetitively on a site when many
pages have similar blocks of functionality. Take, for example, a user login control. This control could be
created as a user control by using a couple of textboxes and labels.
Another example is a menu control that applies different formatting to a page link if the page is
currently being viewed, or displays a submenu for that page. A user control is saved with a
.ascx file
extension, and can be called from any of the ASP.NET pages in our application by using just two lines of
code. The main principle of user controls is that you essentially cut out a portion of code from your
436
Chapter 12
ASP.NET page and paste it into a user control, where it will work just fine as long as the ASP.NET page
knows where to find the code and where to put it.

Let's look at a few pros and cons of using user controls in your applications. User controls are ideal for:
❑ Using repetitive elements (such as headers, menus, login controls, and so on) on pages
❑ Reducing the amount of code per page by encapsulating repetitive elements
❑ Improving page performance by using caching functionality available to user controls for
frequently viewed
However, some situations aren't ideal for using user controls. These include:
❑ Separation of presentation HTML from the code blocks (use code-behind, discussed later in this
chapter)
❑ Encapsulation of data access methods in a reusable package (use pre-compiled assemblies,
discussed in the next chapter)
❑ Creating a control that can be reused more widely than in just your application (use custom
server controls, discussed in the next chapter)
It's time to start looking at code. This chapter and the next will look at creating custom reusable elements
in ASP.NET pages, showing how these elements can all be plugged together with minimal fuss, to
produce a very clean
.aspx file by hiding advanced functionality within reusable components. The next
example demonstrates user controls in action.In this example, we will discuss a very basic example (to
show the theory), which will be followed by a more complex example. We'll add a simple header control
to the default page of the Wrox United application.
Try It Out Our First User Control
1.
Start by creating a new ASP.NET user control within the Wrox United folder as shown in Figure
12-4 and name it
SimpleHeader.ascx (note the different file extension – .ascx, not .aspx):
Figure 12-4
437
Reusable Code for ASP.NET
2. In the new file, switch to HTML view – notice that there is hardly anything in the file when it's
first created! All you need to do here is add one line of code:
<h1>Wrox United</h1>

3. Save this file and reopen Default.aspx from the Wrox United application. We'll replace the
heading in this page with the newly created user control. To do this, Switch to
All view – notice
the yellow highlighted lines (which aren't visible in any other view) at the top of the file. This is
where you need to add the first piece of code. Add the following highlighted line of code:
<%@ Page Language="C#" %>
<%@ Register TagPrefix="WroxUnited" TagName="SimpleHeader"
Src="SimpleHeader.ascx" %>
5. Switch back to HTML view. Replace the <h1> </h1> section with the highlighted code:
<form runat="server">
<WroxUnited:SimpleHeader id="HeaderControl" runat="server"/>
<table width="800">

6. That's about all you need to add to the code! If you switch over to the Design view as shown in
Figure 12-5, you'll see that the control has been added:
Figure 12-5
438
Chapter 12
7. It's time to try it out – run the page and you should see the familiar front page of the site as
shown in Figure 12-6:
Figure 12-6
Notice that the front page looks the same as before, and the new title has the correct style applied to it as
if it were still a part of the main page.
How It Works
Having completed this example, you won't see any difference in the rendered page when it is run and
the page that we built in the last chapter. However, the technique that we implemented behind the
scenes (changing the hard-coded HTML to a reusable control) can prove to be very useful, as you'll see
for yourself later in this chapter.
If you open up
SimpleHeader.ascx in the All view in Web Matrix, you'll see the following:

<%@ Control Language="C#" %>
<script runat="server">
// Insert user control code here
//
</script>
<! Insert content here >
<h1>Wrox United
</h1>
439
Reusable Code for ASP.NET
The default code that Web Matrix added is quite light. There are a couple of comments, an unused script
block, and a special directive at the top of the code. The first line of code tells the compiler that we wrote
this control in C#. The only code added to the page was the
<h1>Wrox United</h1> line. This line of
code can be displayed on any code that uses this control.Let's look at the 'consumer' of our ASCX user
control, the Default.aspx page:
<%@ Page Language="C#" %>
<%@ Register TagPrefix="WroxUnited" TagName="SimpleHeader"
Src="SimpleHeader.ascx" %>
The first line of code links the ASCX control to the ASPX page. This tag must appear at the top of your
page, before any HTML code. Two attributes have been set for the
Register directive:

TagPrefix
❑ TagName
TagPrefix
is the collective name for our group of controls, and TagName is the name of this specific
control. For example, to use an ASP.NET textbox control on an ASPX page, we use the syntax
<asp:textbox />. A TagPrefix precedes the colon and a TagName follows the colon. For an ASP.NET
textbox,

<asp: > would be the TagPrefix, and < :textbox>would be the TagName.
In this example, the
TagPrefix for the new user control was set to WroxUnited, and the TagName was
set to
SimpleHeader. To use the control on a page, you use the <WroxUnited:SimpleHeader /> tag.
You could have a whole library of
WroxUnited tags, each identified by a different TagName in the code.
The final part of the directive specifies the source file of the user control. Note that ASP.NET expects this
file to be in the same place as the
.aspx file. If this is not the case, then add either a relative or an
absolute path here.Then we embedded the user control into the
Default.aspx page:
<WroxUnited:SimpleHeader id="HeaderControl" runat="server"/>
Here you can see the WroxUnited:SimpleHeader syntax discussed earlier. The control is added to the
page using the
TagName and TagPrefix specified in the attribute declaration at the top of the page.
Web Matrix can provide a preview of pages that include user controls, so you could see the output of the
user control that you have added in
Design view. The result is that the page is rendered in exactly the
same way as before. The HTML code from the control is rendered within the HTML of the page.
While this user control could be implemented on every page in the site easily, this isn't exactly the most
exciting control that we could use. Let's work on a visually appealing header control that can be
displayed at the top of every page in the site.Let's create a user control that forms a header for the Wrox
United Web site. Our example used a few images, including a team logo and pictures of the players.
These images are available for download, along with the rest of the code for the book, from
/>Try It Out Wrox United – Header Control
1.
Open up Web Matrix and create a new ASP.NET user control called header.ascx. Enter the
following code in the
HTML view:

<table width="100%">
440
Chapter 12
<tr style="BACKGROUND-IMAGE: url(images/headbg.gif);"><td>
<table width="800">
<tr style="VERTICAL-ALIGN: middle">
<td style="TEXT-ALIGN: left" width="200">
<a href="default.aspx"><img src="images/logo.gif" border="0"></a>
</td>
<td style="TEXT-ALIGN: center" width="400">
<img src="images/teamlogo.gif" />
</td>
<td style="TEXT-ALIGN: right" width="200">
<asp:AdRotator id="AdRotator1" runat="server"
Height="95px" Width="100px"
AdvertisementFile="faces.xml"></asp:AdRotator>
</td>
</tr>
</table>
</td></tr>
</table>
<h2><%= PageTitle %></h2>
2. Switch to Code view and enter the following line of text:
public string PageTitle = "";""
3. Save this file as header.ascx. You'll notice an ASP.NET AdRotator control in this file. This
control depends on the contents of an XML file. Let's create this. by creating a new blank XML
page called
faces.xml and adding the following code to it:
<?xml version="1.0" encoding="utf-8" ?>
<Advertisements>

<Ad>
<ImageUrl>images/chrish_s_t.gif</ImageUrl>
<NavigateUrl>players.aspx</NavigateUrl>
<AlternateText>Player: Chris Hart</AlternateText>
<Impressions>80</Impressions>
<Keyword>ChrisH</Keyword>
</Ad>
<Ad>
<ImageUrl>images/chrisu_s_t.gif</ImageUrl>
<NavigateUrl>players.aspx</NavigateUrl>
<AlternateText>Player: Chris Ullman</AlternateText>
<Impressions>80</Impressions>
<Keyword>ChrisU</Keyword>
</Ad>
<Ad>
<ImageUrl>images/dave_s_t.gif</ImageUrl>
<NavigateUrl>players.aspx</NavigateUrl>
<AlternateText>Player: Dave Sussman</AlternateText>
<Impressions>80</Impressions>
<Keyword>Dave</Keyword>
</Ad>
441
Reusable Code for ASP.NET
<Ad>
<ImageUrl>images/john_s_t.gif</ImageUrl>
<NavigateUrl>players.aspx</NavigateUrl>
<AlternateText>Player: John Kauffman</AlternateText>
<Impressions>80</Impressions>
<Keyword>John</Keyword>
</Ad>

</Advertisements>
We'll examine how the AdRotator control works in just a few moments, but for now, add the
new header control to the default page by altering a couple of lines.
5. Change the declaration at the top of the page in Default.aspx:
<%@ Page Language="C#" %>
<%@ Register TagPrefix="WroxUnited" TagName="Header" Src="header.ascx" %>
6. Change the code that embeds the header control in the page as follows:
<form runat="server">
<WroxUnited:Header id="HeaderControl" runat="server"></WroxUnited:Header>
<table width="800">

7. Save the file again and view it in your browser. The page is shown in Figure 12-7:
Figure 12-7
442
Chapter 12
How It Works
In this example, we implemented another simple user control and introduced the AdRotator control.
This control is traditionally used to store banner advertisements and rotate the visible advertisement
according to a random algorithm. Each time the page is refreshed, an advertisement is selected for
display. The frequency with which each advert appears on the page depends on the weightage we give
to each advertisement. In this example, each ad is given equal weightage so adverts display for equal
intervals of time but in a random fashion whenever the page is refreshed.
In this example, the
AdRotator control was used to display images of the members of the team (instead
of displaying ads) and to change the image on subsequent visits to the site. The information that controls
which images to display and how often to display them is stored in an XML file.
Let's break down the code and work through what we did. First, the
header.ascx control:
<table width="100%">
<tr style="BACKGROUND-IMAGE: url(images/headbg.gif);"><td>

<table width="800">
<tr style="VERTICAL-ALIGN: middle">
<td style="TEXT-ALIGN: left" width="200">
<a href="default.aspx"><img src="images/logo.gif" border="0"></a>
</td>
<td style="TEXT-ALIGN: center" width="400">
<img src="images/teamlogo.gif" />
</td>
<td style="TEXT-ALIGN: right" width="200">
<asp:AdRotator id="AdRotator1" runat="server"
Height="95px" Width="100px"
AdvertisementFile="faces.xml"></asp:AdRotator>
</td>
</tr>
</table>
</td></tr>
</table>
<h2><%= PageTitle %></h2>
This control is made up of one large table that contains a sub-table with three cells. We applied a style to
the single row in the parent table. The addition of a background image to this row resulted in this style
being applied as a solid background for the whole header. The inner table helps to organize the contents
of the header. The contents of the row were centered along a horizontal axis:
<tr style="VERTICAL-ALIGN: middle">
Then, each of the three cells were aligned to the left, center, or right of the vertical axis of each cell
respectively:
<td style="TEXT-ALIGN: left" width="200">
In the first two cells, a couple of static images were added. Notice that the image in the first cell is
wrapped in an HTML anchor (<
A >) tag, which will turn the image into a hyperlink. In this case,
clicking the first image would take the user to the front page, thus making it a handy 'home' button that

users can use to return to the default page.
443
Reusable Code for ASP.NET
In the third cell, we added an AdRotator control:
<asp:AdRotator id="AdRotator1" runat="server"
Height="95px" Width="100px"
AdvertisementFile="faces.xml"></asp:AdRotator>
The control declaration is very simple, but the most interesting part is the link to the
AdvertisementFile XML file, which controls how AdRotator works. Let's look at an extract of that
file:
<?xml version="1.0" encoding="utf-8" ?>
<Advertisements>
<Ad>
<ImageUrl>images/chrish_s_t.gif</ImageUrl>
<NavigateUrl>players.aspx</NavigateUrl>
<AlternateText>Player: Chris Hart</AlternateText>
<Impressions>80</Impressions>
<Keyword>ChrisH</Keyword>
</Ad>
<Ad>

</Ad>
</Advertisements>
The settings that control what is displayed and what functionality is available each time the page is
loaded, are contained within an
<Advertisements> </Advertisements> tag. Each displayed item
is defined within an
<Ad> </Ad> element. In this example, you can see the element definition for
Chris Hart. Let's work through each of the tags for this player. The first tag specifies the image to be
displayed for this player. Here, the image is a small one with a transparent background (available along

with the code downloads for this book):
<ImageUrl>images/chrish_s_t.gif</ImageUrl>
The <NavigateUrl> tag specifies the path to which the browser will navigate when the image is
clicked. Here we specified the
Players.aspx page:
<NavigateUrl>players.aspx</NavigateUrl>
The <AlternateText> tag controls the text that is displayed when the mouse pointer hovers over the
image, as well as the text that is read out to assist visually-impaired surfers:
<AlternateText>Player: Chris Hart</AlternateText>
The <Impressions> tag controls the weightage that affects how often this advertisement (or image) is
displayed as compared to other advertisements. In this example, all players have equal weighting, but
you could indicate a preference for your favorite player by increasing the number for that particular
image element:
444
Chapter 12
<Impressions>80</Impressions>
The last tag controls the keyword for the advert. This element is optional, but you can use it to filter
advertisements by including a
KeywordFilter attribute to the <ASP:AdRotator > tag in your
ASP.NET pages:
<Keyword>ChrisH</Keyword>
The last piece of the puzzle involves including this header on the Default.aspx page. You only need to
make a couple of minor changes (including adding a directive at the top of the page) to specify that you
want to use the new header file in the page:
<%@ Register TagPrefix="WroxUnited" TagName="Header" Src="Header.ascx" %>
You can then use the control in the page by including the following line of code:
<WroxUnited:Header id="HeaderControl" runat="server"></WroxUnited:Header>
Before we move on, don't forget that you could include this header control on all the pages of the Wrox
United site in the same way. With this in mind, we added an interactive element to this header control.
Recall the last line in the

Header control itself:
<h2><%= PageTitle %></h2>
This line of text will create a Heading 2 style paragraph, and add the text contents of the PageTitle
public variable to the page:
public string PageTitle = "";""
Take the Chat application as an example; add two lines of code to the Chat.aspx page to see this in
action (assuming that you've already added code to add the selected CSS theme to the page). First, at the
top of the page, add the following:
<%@ Register TagPrefix="WroxUnited" TagName="Header" Src="Header.ascx" %>
Then add the following tag (instead of the Heading 1 and 2 tags) to the HTML view of the page:
<form runat="server">
<WroxUnited:Header id="HeaderControl" runat="server" PageTitle="Online
Chat"></WroxUnited:Header>
<asp:TextBox id="txtChatBox" runat="server" TextMode="MultiLine"
Height="200px" Width="550px" ReadOnly="true"></asp:TextBox>
When you view this page in your browser, it should appear as shown in Figure 12-8:
Keep the total of all the values in the <Impressions> tags under 2 billion to avoid a
runtime error.
445
Reusable Code for ASP.NET
Figure 12-8
Heading 2 text has been included on the page, thanks to the PageTitle attribute in the control's
declaration. This is a neat trick for making header controls a bit more interactive, removing standard
code from the main pages, and also ensuring that the look and feel of all pages is maintained centrally.
Let's look at a slightly different type of user control. This control can be used as a navigation bar, like the
links on the left of the front page. An advantage is that it can be added to all the pages in the site with
minimal code reuse.
Try It Out Wrox United – Navigation User Control
In this example, we will take the ASP.NET hyperlink controls from Default.aspx along with the
associated code from the left-hand side of the page and place it in a user control.

1. Create a new user control called Navbar.ascx and add the following code:
<div class="navbar">
</div>
We will add code between these tags in just a moment.
446
Chapter 12

×