Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Pro ASP.NET 2.0 In CSharp 2005 (2005) [eng]

.pdf
Скачиваний:
107
Добавлен:
16.08.2013
Размер:
29.8 Mб
Скачать

538 C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

If you use named skins, you can set the SkinID of a control declaratively when you design the page, or you can specify it dynamically in your code.

Caution If you use named skins, you’ll need to be careful that every theme uses the same names and provides tags for the same controls. If a control specifies the SkinID attribute and ASP.NET can’t find a matching skin for that control in the theme, the control won’t be themed, and it will keep its current formatting.

Standardizing Website Layout

Standardizing the formatting of your website is only half the battle. You also need to make sure that common elements, such as your website header and site navigation controls, appear in the same position on every page.

The challenge is to create a simple, flexible layout that can be replicated throughout your entire website. You can use three basic approaches:

User controls: User controls allow you to define a “pagelet”—a portion of a web page, complete with markup and server-side code, that can be reused on as many web forms as you want. User controls are a great way to standardize a common page element. However, they can’t solve the layout problem on their own, because there’s no way to ensure that user controls are placed in the same position on every page. Chapter 14 describes user controls.

HTML frames: Frames are a basic tool of HTML that allow you to show more than one page in a browser window at once. The key disadvantage of frames is that each page is retrieved through a separate request to the server, and as a result the code on each page must be completely independent. That means a page in one frame can’t communicate with or influence a page in another frame (at least not through server-side code). The one advantage that frames

give that can’t be duplicated by any other feature is isolated scrolling, which means each frame can be scrolled separately.

Master pages: Master pages are a new innovation in ASP.NET that are designed specifically for standardizing web-page layout. Master pages are web-page templates that can define fixed content and declare the portion of the web page where you can insert custom content. If you use the same master page throughout your website, you’re guaranteed to keep the same layout. Best of all, if you change the master page definition after applying it, all the web pages that use it inherit the change automatically.

In ASP.NET, master pages are the preferred option, and you’ll see them at work throughout the rest of this chapter. Frames offer a clumsier programming model but are required if you want to fix a portion of your page in place while allowing scrolling in another section. If you want to learn more about frames, refer to Chapter 29 for the basics and for several ASP.NET workarounds.

Master Page Basics

Many loyal ASP developers were surprised to find that ASP.NET 1.0 and 1.1 didn’t include any facility for creating page templates—a must for building a coherent site. Although some workarounds were proposed, these custom solutions still had drawbacks and often didn’t integrate well with the Visual

C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

539

Studio design environment. Adding to the disappointment was that Windows Forms (the .NET toolkit for Windows user interfaces) included a model for reusable form templates, although even that was far from perfect. Finally, ASP.NET 2.0 fills the gap with a comprehensive new feature called master pages.

To provide a practical, flexible solution for page templating, a number of requirements must be met:

The ability to define a portion of a page separately and reuse it on multiple pages.

The ability to create a locked-in layout that defines editable regions. Pages that reuse this template are then constrained to adding or modifying content in the allowed regions.

The ability to allow some customization of the elements you reuse on each page.

The ability to bind a page to a page template declaratively (with no code) or to bind to a page dynamically at runtime.

The ability to design a page that uses a page template with a tool such as Visual Studio.

Master pages meet all of these requirements. They provide a system for reusing templates, a way to limit how templates can be modified, and rich design-time support.

For this to work, ASP.NET defines two new types of pages: master pages and content pages. A master page is a page template. Like an ordinary ASP.NET web page, it can contain any combination of HTML, web controls, and even code. In addition, master pages can include content placeholders—defined regions that can be modified. Each content page references a single master

page and acquires its layout and content. In addition, the content page can add page-specific content in any of the placeholders. In other words, the content page fills in the missing pieces that the master page doesn’t define.

For example, in a typical website, a master page might include a fixed element such as a header and a content placeholder for the rest of the page. The content page then acquires the header for free and supplies additional content.

To take a closer look at how this works, it helps to consider the example presented in the following sections.

A Simple Master Page

To create a master page in Visual Studio, select Website Add New Item from the menu. Select Master Page, give it a filename, and click OK.

A master page is similar to an ordinary ASP.NET web form. Like a web form, the master page can include HTML, web controls, and code (either in an inline script block or in a separate file). One difference is that while web forms start with the Page directive, a master page starts with a Master directive that specifies the same information, as shown here:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="SiteTemplate.master.cs" Inherits="SiteTemplate_master" %>

Another difference between master pages and ordinary web forms is that master pages can use the ContentPlaceHolder control, which isn’t allowed in ordinary pages. The ContentPlaceHolder is a portion of the page where the content page can insert content. When you create a new master page in Visual Studio, you start with a blank page that includes a single ContentPlaceHolder control (see Figure 15-9), although you can add as many as you need.

540 C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

Figure 15-9. A new master page

The ContentPlaceHolder doesn’t have any remarkable properties. Here’s an example that creates a master page with a static banner followed by a ContentPlaceHolder and then a footer (shown in Figure 15-10):

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="SiteTemplate.master.cs" Inherits="SiteTemplate_master" %>

<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">

<title>Untitled Page</title> </head>

<body>

<form id="form1" runat="server"> <table width="100%">

<tr>

<td bgcolor="black" style="...">

<img align="left" src="headerleft.jpg" /> <img align="right" src="headerright.jpg" /> <br />My Site<br />

</td>

</tr>

</table> <br />

<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder>

<br />

<em>Copyright © 2005.</em> </form>

</body>

</html>

C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

541

Figure 15-10. A master page at design time

Master pages can’t be requested directly. To use a master page, you need to build a linked content page.

A Simple Content Page

To use your master page in another web page, you need to add the MasterPageFile attribute to the Page directive. This attribute indicates the filename of the master you want to use:

<%@ Page Language="C#" MasterPageFile="~/SiteTemplate.master" ... %>

Notice that the MasterPageFile attribute begins with the path ~/ to specify the root website folder. If you just specify the filename, ASP.NET checks a predetermined subfolder (named MasterPages) for your master page. If you haven’t created this folder or your master page isn’t there, it checks the root of your web folder next.

Setting the MasterPageFile attribute isn’t enough to transform an ordinary page into a content page. The problem is that content pages have a single responsibility—to define the content that will be inserted in one or more ContentPlaceHolder controls (and to write any code you need for these controls). A content page doesn’t define the page, because the outer shell is already provided by the master page. As a result, attempting to include elements such as <html>, <head>, and <body> will fail, because they’re already defined in the master page.

To provide content for a ContentPlaceHolder, you use another specialized control, called Content. The ContentPlaceHolder control and the Content control have a one-to-one relationship. For each ContentPlaceHolder in the master page, the content page supplies a matching Content control (unless you don’t want to supply any content at all for that region). ASP.NET links the Content control to the appropriate ContentPlaceHolder by matching the ID of the ContentPlaceHolder with the Content.ContentPlaceHolderID property of the corresponding Content control. If you create a Content control that references a nonexistent ContentPlaceHolder, you’ll receive an error.

542 C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

Tip To make it even easier to create a new content page, let Visual Studio guide you. Just select Website Add New Item from the menu. Select Web Form, click the Select Master Page File check box, and click OK. Visual Studio will prompt you to choose a master page file from your current web project. When you take this step,

Visual Studio automatically creates a Content control for every ContentPlaceHolder in the master page.

Thus, to create a complete content page that uses the SiteTemplate master page, you simply need to fill in the content for the ContentPlaceHolder with the ID ContentPlaceHolder1. Here’s an example that shows the complete page code:

<%@ Page Language="C#" MasterPageFile="~/SiteTemplate.master" AutoEventWireup="true" CodeFile="SimpleContentPage.aspx.cs" Inherits="SimpleContentPage_aspx" Title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">

<span style="...">Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun.</span> </asp:Content>

As you can see, content pages are refreshingly clean, because they don’t include any of the details defined in the master page. Even better, this makes it easy to update your website. All you need to is modify a single master page. As long as you keep the same ContentPlaceHolder controls, the existing content pages will keep working and will fit themselves into the new layout wherever you specify.

Figure 15-11 shows this sample content page.

Figure 15-11. A content page at runtime

C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

543

To get a better understanding of how master pages work under the hood, it’s worth taking a look at a content page with tracing (add the Trace="True" attribute in the Page directive). That way you can study the control hierarchy. What you’ll discover is that ASP.NET creates the control objects for the master page first, including the ContentPlaceHolder, which acts as a container. It then adds the controls from the content page into the ContentPlaceHolder.

Design-Time Quirks with Master Pages

The design-time representation of your content pages can range from excellent to poor. For the simple header and footer example, you’ll see a fairly good representation of your content page that includes all the elements of the master page and the additional content you’ve added. The parts you’ve acquired from the master page will be shaded in gray, indicating you can’t select or change them in any way. Instead, you’ll be limited to inserting comments into the ContentPlaceHolder region, as shown in Figure 15-12.

Figure 15-12. A content page at design time

Tip If a master page defines a ContentPlaceHolder but your content page doesn’t define a corresponding Content control, you’ll see a black box in its place. To add the required Content control, right-click that section of the page and choose Create Custom Content.

However, this design-time representation is a little misleading. That’s because when you run the page, the ContentPlaceHolder section will expand or collapse to fit the content you place in it. If you’ve added volumes of text, the footer won’t appear until the end. And if you’ve included only a single line of text, you’ll see something more compact (as in Figure 15-11).

The main problem is how Visual Studio renders the ContentPlaceHolder and Content controls. Initially, these are shown as empty boxes that expand as you add content. However, no matter how little content you add, the design-time representation of this box won’t shrink beyond a certain set size. As a result, your alignment won’t be faithfully depicted for very small content regions.

544 C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

To see a more dramatic example of this problem, try adding a second ContentPlaceHolder to the master and allowing the user to define a title in the header, with the preset graphics and font:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="SiteTemplate.master.cs" Inherits="SiteTemplate_master" %>

<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">

<title>Untitled Page</title> </head>

<body>

<form id="form1" runat="server"> <table width="100%">

<tr>

<td bgcolor="black" style="...">

<img align="left" src="headerleft.jpg" /> <img align="right" src="headerright.jpg" /> <br />

<asp:ContentPlaceHolder id="TitleContent" runat="server"> </asp:ContentPlaceHolder>

<br /> </td>

</tr>

</table> <br />

<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder>

<br />

<em>Copyright © 2005.</em> </form>

</body>

</html>

Now you can easily set the banner text in the content page by adding a second Content control:

<%@ Page Language="C#" MasterPageFile="~/SiteTemplate.master" AutoEventWireup="true" CodeFile="SimpleContentPage.aspx.cs" Inherits="SimpleContentPage_aspx" Title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">

<span style="...">Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun.</span> </asp:Content>

<asp:Content ContentPlaceHolderID="TitleContent" ID="Content2" runat="server"> Custom Title</asp:Content>

Figure 15-13 compares what you’ll see at design time with what you’ll see at runtime. Not only is the text unreadable (because the white font color from the master page isn’t applied at design time), but also the layout is scrambled because of the minimum display size that the Content control uses at design time.

C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

545

Figure 15-13. The design-time and runtime view of a more complex content page

Tip When creating master pages that don’t use tables, make sure you include a <br /> line break after your ContentPlaceHolder, if needed. In the design environment, the ContentPlaceHolder is shown as a box that takes the full width of the design surface. As a result, content that appears after it always starts on the line underneath. However, if you haven’t added a line break, in your content page you’ll see a different behavior—namely, the content in the ContentPlaceHolder placeholder will run directly into the following content.

546 C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

Default Content

When the master page defines a ContentPlaceHolder, it can also include default content—content that will be used only if the content page doesn’t supply a corresponding Content control.

To get this effect, all you need to do is place the appropriate HTML or web controls in the ContentPlaceHolder tag. (You can do this by hand using the .aspx markup or just by dragging and dropping controls into the ContentPlaceHolder.)

Here’s an example that adds default content to the banner text from the previous example:

<asp:ContentPlaceHolder id="TitleContent" runat="server"> Master Pages Website

</asp:ContentPlaceHolder>

If you create a content page in Visual Studio, you won’t notice any immediate change. That’s because Visual Studio automatically creates a <Content> tag for each ContentPlaceHolder. When a content page includes a <Content> tag, it automatically overrides the default content. However, if you delete the <Content> tag, you’ll see the default content in its place—the new “Master Pages Website” banner text.

Note Content pages can’t use just a portion of the default content or just edit it slightly. This isn’t possible because the default content is stored only in the master page, not in the content page. As a result, you need to decide between using the default content as is or replacing it completely.

A More Practical Master Page

For the most part, HTML uses a flow-based layout. That means as more content is added, the page is reorganized and other content is bumped out the way. This layout can make it difficult to get the result you want with master pages. For example, if you aren’t careful, you could craft the perfect layout, only to have the structure distorted by a huge block of information that’s inserted into a <Content> tag.

To control these problems, most master pages will use either HTML tables or CSS positioning to control the layout.

With tables, the basic principle is to divide all or a portion of the page into columns and rows. You can then add a ContentPlaceHolder in a single cell, ensuring that the other content is aligned more or less the way you want. With CSS positioning, the idea is to separate your content into <div> tags and position these <div> tags by using absolute coordinates or by floating them on one side of the page. You’ll then place the ContentPlaceHolder in the <div> tag.

Tip For some great examples of CSS-based layout, see the sites http://www.csszengarden.com and http://www.bluerobot.com/web/layouts.

The following example shows how you can use master pages to create a traditional web application with a header, footer, and navigation bar, all of which are defined with tables. Figure 15-14 shows how this structure is broken up into a table.

C H A P T E R 1 5 T H E M E S A N D M A S T E R PA G E S

547

Figure 15-14. A table-based layout

 

Here’s the markup for the table:

<table width="100%">

<tr><td colspan="2">My Header</td></tr> <tr>

<td width="150px">Navigation Controls</td> <td>

<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder>

</td>

</tr>

<tr><td colspan="2">My Footer</td></tr> </table>

Tip To a quick refresher on HTML tables, complete with information about how to specify borders, cell sizes, alignment, and more, refer to the examples at http://www.w3schools.com/html/html_tables.asp.

Figure 15-15 shows the resulting master page and a content page that uses the master page.

To convert this example into something more practical, just replace the static text in the master page with the actual header, navigation controls, and footer you really want. All the child pages will acquire these features automatically. This is the first step for defining a practical structure for your entire website.