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

Real - World ASP .NET—Building a Content Management System - StephenR. G. Fraser

.pdf
Скачиваний:
68
Добавлен:
24.05.2014
Размер:
4.59 Mб
Скачать

User Controls

I hinted in Chapter 11 that Web frames are being replaced on the Internet by a new approach. In the ASP.NET world, this new approach is the User Control. You might think of User Control as a reusable section of code that can be inserted into a Web page. Early betas called these things Pagelets. Personally, I think the term "Pagelet" was a good name for them, but hey, it wasn't my call.

User Controls provide Web developers with a quick way to add the same little section of a Web page to multiple Web pages. Developers create a User Control once and then deploy it to as many Web pages as they like. Something in the User Control that gets changed immediately shows up in all Web pages that use the User Control. No longer do you have to wade through multiple pages to make the same correction to all of them.

Here are three things that a developer needs to know about User Controls:

§User Controls are basically the same thing as a Web form, except they don't have an <HTML>, <BODY>, or <FORM> tag. This obviously is because a Web page is only allowed one copy of these, and the main Web form will already have them.

§A User Control has a suffix of .acsx, enabling the compiler to differentiate between a Web form and a User Control. Also, it stops the compiler from generating an error for the missing aforementioned tags.

§A User Control cannot execute on its own. It has to be inserted into a Web form to run. Personally, I like to lay out the Web form using a table and then insert the appropriate User Control into each table cell. This is not required, though. You can use a User Control just as you do any HTML or intrinsic control. Therefore, you can place them however you like on a Web form.

Other than that, there isn't much to User Controls.

Creating a User Control in the Visual Studio .NET design tool is very similar to creating a Web form. The only differences are that you select Add Web User Control instead of Add Web Form from the Project menu and you make sure that the Web User Control icon is selected instead of the Web Form icon when opening the new item from the dialog box. Once the User Control is active in the design window, you design exactly as you do with a Web form.

Standard CMS.NET User Controls

Every Web page in CMS.NET has a header, a footer, and a NavBar. It only makes sense that these three be created as User Controls because they are nearly the same for each page, and if you change something in any of them, you are going to want to have it reflected in every Web page.

Header User Control

The design of the Header User Control only requires the dragging of an image control and a horizontal rule to the Header.ascx design window. Listing 13-4 shows the ASP.NET design code generated for this User Control.

Listing 13-4: The Header User Control Design Code

<%@ Control Language="c#" AutoEventWireup="false"

Codebehind="Header.ascx.cs"

Inherits="CMSNET.CDA.Header"%>

<asp:image id=imgHeader runat="server"></asp:Image><B R>

<HR width="100%" SIZE=1>

What do you know? It contains an image control and a horizontal rule (sarcasm intended). If you had created this as a Web form, it would also include <HTML>,

<BODY>, and <FORM>, but because this is a User Control, these tags are missing. CMS.NET provides a little navigational tip in the header because the header image is different for each zone and level. The image control in the design code in Listing 13-4 shows no reference to which image to display. You might think of the control as a placeholder for an image, which the Codebehind eventually populates.

The Header User Control Page_Load() method (see Listing 13-5) shows how the image is loaded onto the User Control by placing the image's URL in the ImageURL property. The question that needs to be asked is this: What is this level variable found in the ImageURL string?

Listing 13-5: The Header User Control Codebehind Page_Load Method

private void Page_Load(object sender, System.EventArgs e)

{

imgHeader.ImageUrl = "Images/" + level + ".jpg";

}

The answer is in Listing 13-6. It is simply a property that you manually add to the User Control. It is up to the Web form that calls this User Control to populate the property. You will see when you develop the home page Web form how to populate the property.

Listing 13-6: The Header User Control Codebehind Level Property

public string Level

{

get

{

return level;

}

set

{

level = value;

}

}

NavBar User Control

CMS.NET could have continued to use an XML-driven NavBar, but due to the future plans for personalization and the need to dynamically change the NavBar, you now use a database-driven version.

As you can see in Listing 13-7, all that the NavBar User Control design code contains is a table control, which you will proceed to populate in the Codebehind. Again, no

<HTML>, <BODY>, or <FORM> tags exist anywhere.

Listing 13-7: The NavBar User Control Design Code

<%@ Control Language="c#" AutoEventWireup="false"

Codebehind="NavBar.ascx.cs"

Inherits="CMSNET.CDA.NavBar"%>

<asp:Table id=tblNavBar runat="server" CellPadding="4"></asp:Table>

The process of building a NavBar from a database is, in this case, easier than building one using XML. All it does is simply loop through all the records in the Domain database table and build a hyperlink from the DomainType column. The code also does a comparison on the value provided by the User Control's Domain property, which contains the current active domain, to the database column. If they match, a literal text is created instead of a hyperlink. There is no reason for a page to hyperlink to itself.

Listing 13-8: The NavBar User Control Codebehind

private void Page_Load(object sender, System.EventArgs e)

{

if (!IsPostBack)

{

Domain domain = new Domain(new AppEnv(Context).GetConnection());

DataTable dt = domain.GetAll();

TableCell cell;

HyperLink link;

LiteralControl lit;

foreach (DataRow dr in dt.Rows)

{

TableRow row = new TableRow(); tblNavBar.Rows.Add(row);

cell = new TableCell();

if (m_domain != Convert.ToInt32(dr["DomainID"]))

{

link = new HyperLink(); link.Text = dr["Title"].ToString();

link.NavigateUrl = dr["DomainType"].ToString().Trim() + ".aspx?Domain=" + dr["DomainID"];

cell.Controls.Add(link);

}

else

{

lit = new LiteralControl(dr["Title"].ToString());

cell.Controls.Add(lit);

}

row.Cells.Add(cell);

}

}

}

public int Domain

{

get

{

return m_domain;

}

set

{

m_domain = value;

}

}

Footer User Control

The footer area of CMS.NET is currently just a stub because there are no Web pages for Contact, Company, Contributors, Jobs, or Advertising. The design only makes it look like there are.

The footer does include navigational links. In fact, they are the same as the links found on the NavBar. Why the duplication? Because CMS.NET is not using frames, when a user scrolls down to read the whole story, the NavBar scrolls at the same time. Having the navigation at the bottom saves the user from having to scroll back up the page to navigate to another place.

Listing 13-9 shows the Footer User Control. The navigation links will be added to the tblFootMenu table in the Codebehind. Note that there are no hyperlinks to the other Web pages. The design is only written to look like there are.

Listing 13-9: The Footer User Control Design Code

<center>

<asp:Table id=tblFootMenu runat="server" CellPadding="3"></asp:Table>

</center>

<HR width="60%" SIZE=1>

<center>

 <U><FONT color=#0a246a>Contact Us</FONT></U> |

<U><FONT color=#0a246a>Company Info</FONT></U> |

<U><FONT color=#0a246a>Contributors</FONT></U> |

<U><FONT color=#0a246a>Jobs</FONT></U> |

<U><FONT color=#0a246a>Advertising</FONT></U>

<br>

<FONT size=2>Copyright © 2001 Contentmgr.com. All rights reserved.</FONT>

</center>

As you can see in Listing 13-10, the Footer User Control's Codebehind is nearly identical to that of the NavBar User Control. There are two differences, though. This time, a hyperlink is generated even if it is to the same page. When clicked, this hyperlink jumps the user back to the top of the page.

Listing 13-10: The Footer User Control Codebehind

private void Page_Load(object sender, System.EventArgs e)

{

Domain domain = new Domain(new AppEnv(Context).GetConnection());

DataTable dt = domain.GetAll();

TableCell cell;

HyperLink link;

TableRow row = new TableRow();

tblFootMenu.Rows.Add(row);

foreach (DataRow dr in dt.Rows)

{

cell = new TableCell();

link = new HyperLink();

link.Text = dr["Title"].ToString();

link.NavigateUrl = dr["DomainType"].ToString().Trim() +

".aspx?Domain=" + dr["DomainID"];

cell.Controls.Add(link);

row.Cells.Add(cell);

}

cell = new TableCell();

link = new HyperLink();

link.Text = "Back";

link.NavigateUrl = "javascript:history.go(-1);";

cell.Controls.Add(link);

row.Cells.Add(cell);

}

The second difference is the use of JavaScript to navigate to previous pages. There is no elegant way of doing this in C#, so I had to revert back to my days as a JavaScript programmer to see how it was done. Lucky for me, all it takes is to place the JavaScript history.go function in the NavigateURL property.

The Default Home Page Web Form

Now that you have the standard User Controls used by the home page form, let's go ahead and implement them in the default home page. You will only implement the default version of CMS.NET's Web pages in this chapter. The default pages are those pages that everyone initially sees when entering the Web site.

You might remember the standard Web page layout shown in Figure 13-10 from Chapter 11. In Chapter 11, you used this layout to break up a Web page using a frameset. In this chapter, you will use this same layout, but instead of using frames, you will use a standard HTML table. (You don't have any ads, so you won't create the ads section.)

Figure 13-10: The standard Web page layout

From the developer's perspective, the process of using tables and User Controls is very similar to using framesets and Web forms. The only real difference is that you are dragging User Controls to table cells instead of dragging Web forms to frames. The biggest difference is what the user sees. Now, instead of the user having only a small frame to look at, she has the full browser window to use to see the content. When the user scrolls up, down, left, or right, the whole browser view window scrolls, not just a small frame of it. This enables the user to see more content at any one time. CMS.NET's home page is shown in Figure 13-11. It looks like any other home page (albeit pretty empty), with its header, content navigation bar, footer, and main body. I'm sure your home page will have a little more pizzazz. In fact, it had better!

Figure 13-11: The CMS.NET home page

Home Page Web Design

Designing the home page is a snap. Simply create a table and then drag the appropriate User Controls from the Solution Explorer. Let's pretend you don't have the design tool and see what you need to design it manually.

Adding User Controls to Web Forms

Two new things have to be added to a Web form to handle User Controls. The first new thing that you see in the home page design code (see Listing 13-11) is the @Register directive at the top of the Web form. This tells the Web page about the User Control it is about to use.

Listing 13-11: The Home Page Design Code

<%@ Page language="c#" Codebehind="HomePg.aspx.cs" AutoEventWireup="false"

Inherits="CMSNET.CDA.HomePg" %>

<%@ Register TagPrefix="cmsnet" TagName="Header" Src="Header.ascx" %>

<%@ Register TagPrefix="cmsnet" TagName="NavBar" Src="NavBar.ascx" %>

<%@ Register TagPrefix="cmsnet" TagName="Footer" Src="Footer.ascx" %>

<HTML>

<HEAD>

<title>CMS.NET Home</title>

</HEAD>

<body MS_POSITIONING="FlowLayout">

<form id="HomePg" method="post" runat="server">

<TABLE cellSpacing=8 cellPadding=1 width="100%" border=0>

<TR>

<TD colSpan=2>

<cmsnet:Header id=Header Level="home" runat="server">

</cmsnet:Header>

</TD >

</TR>

<TR>

<TD width="20%"style=" WIDTH: 150px" bgColor=#8cd3ef valign=top >

 <br>

<cmsnet:NavBar id=MainNavBar runat="server" >

</cmsnet:NavBar>

</TD >

<TD width="80%">

<H1><FONT color=darkslategray >Welcome to CMS.NET!</FONT></H1>

<P>(Add home page stuff here)</P>

</TD >

</TR>

<TR>

<TD colSpan=2>

<cmsnet:Footer id=Footer runat="server" >

</cmsnet:Footer>

</TD >

</TR>

</TABLE>

</form>

</body>

</HTML>

<%@ Register TagPrefix="cmsnet" TagName="Header" Src="Header.ascx" %>

It contains three attributes:

§TagPrefix: An alias to associate the User Control with a namespace. Basically, it allows multiple User Controls with the same TagName to be unique.

§TagName: An alias to associate the User Control with its class. In other words, it is the class name used in the Codebehind.

§Src: The source code location (relative or absolute) of the User

Control.

The second new thing is the actual User Control element that you add where you want the User Control to be displayed. Basically, it is TagPrefix:TagName, any id you want, and the runat="server" attribute.

<cmsnet:Header id=Header Level="home" runat="server">

The code generated by the design tool does not include any properties that may be required by the User Control. As you see in the preceding line, Level="home" had to be added manually.

Designing the Home Page

Listing 13-11 shows the entire ASP.NET home page design code. The design tool generated most of the code automatically. To make the code more specific to CMS.NET, I changed the TagPrefix from the generic uc1 to cmsnet. I also set the Level property to home. As you will see when you look at the Codebehind, you can also set properties there.

The Home Page Codebehind

The NavBar User Control, which you previously created, has an optional property called Domain. When set, it changes the hyperlink of the specified domain to a literal. This does two things. First, it's another visual clue of the user's location, and second, it stops the user from clicking the redundant, current domain hyperlink.

The Codebehind for the home page is very simple (see Listing 13-12), but it has one catch. The definition of the User Control, unlike intrinsic controls, is not automatically added to the Codebehind. You have to add it manually, so you have to know what class is called. Fortunately, that is provided by the ASP.NET design code, as is its namespace.

Listing 13-12: The Home Page ASP.NET Codebehind

public class HomePg : CMSNET.Common.PageEx

{

protected CMSNET.CDA.NavBar MainNavBar;

private void Page_Load(object sender, System.EventArgs e)

{

int Domain = Convert.ToInt32(Request.QueryString["Domain"]);

// First Time in no Domain specified

if (Domain == 0)

Domain++;

MainNavBar.Domain = Domain;

}

}

Setting User Control Properties in the Codebehind

The current Domain is passed with the Request, except when CMS.NET is accessed the first time and thus is set to the home page domain of 1. You set the Domain property just as you set any other property.

The HeadlineTeaser User Control

CMS.NET's Content-Domain and Zone Web forms both use one additional User Control called HeadlineTeaser. You will see shortly that, unlike the previous User Controls, HeadlineTeaser is dynamically added to Web forms. Dynamically creating User Controls is not difficult to do. It is just not obvious how it is done.

Соседние файлы в предмете Программирование