
Pro CSharp And The .NET 2.0 Platform (2005) [eng]
.pdf

CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS |
865 |
At this point, you should feel quite confident with your knowledge of the architecture of an ASP.NET Page type. Now that you have such a foundation, you can turn your attention to the role of ASP.NET web controls.
■Source Code The PageLifeCycle files are included under the Chapter 23 subdirectory.
Understanding the Nature of Web Controls
Perhaps the major benefit of ASP.NET is the ability to assemble the UI of your pages using the types defined in the System.Web.UI.WebControls namespace. As you have seen, these controls (which go by the names server controls, web controls, or web form controls) are extremely helpful in that they automatically generate the necessary HTML for the requesting browser and expose a set of events that may be processed on the web server. Furthermore, because each ASP.NET control has a corresponding class in the System.Web.UI.WebControls namespace, it can be manipulated in an OO manner from your *.aspx file (within a <script> block) as well as within the associated class defined in the code-behind file.
As you have seen, when you configure the properties a web control using the Visual Studio 2005 Properties window, your edits are recorded in the open declaration of a given widget in the *.aspx file as a series of name/value pairs. Thus, if you add a new TextBox to the designer of a given *.aspx file and change the BorderStyle, BorderWidth, BackColor, Text, and BorderColor properties using the IDE, the opening <asp:TextBox> tag is modified as follows:
<asp:TextBox id=myTextBox runat="server" BorderStyle="Ridge" BorderWidth="5px" BackColor="PaleGreen" BorderColor="DarkOliveGreen" Text = "Yo dude" > </asp:TextBox>
Given that the HTML declaration of a web control eventually becomes a member variable from the System.Web.UI.WebControls namespace (via the dynamic compilation cycle), you are able to interact with the members of this type within a server-side <script> block or the page’s code-behind file, for example:
public partial class _Default : System.Web.UI.Page
{
...
protected void btnChangeTextBoxColor_Click(object sender, EventArgs e)
{
// Modify the HTTP response data for this widget. this.myTextBox.BackColor = System.Drawing.Color.Red;
}
}
All ASP.NET web controls ultimately derive from a common base class named System.Web.UI. WebControls.WebControl. WebControl in turn derives from System.Web.UI.Control (which derives from System.Object). Control and WebControl each define a number of properties common to all server-side controls. Before we examine the inherited functionality, let’s formalize what it means to handle a server-side event.
Qualifying Server-Side Event Handling
Given the current state of the World Wide Web, it is impossible to avoid the fundamental nature of browser/web server interaction. Whenever these two entities communicate, there is always an underlying, stateless, HTTP request-and-response cycle. While ASP.NET server controls do a great deal to shield you from the details of the raw HTTP protocol, always remember that treating the


CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS |
867 |
Table 23-9. Select Members of System.Web.UI.Control
Member |
Meaning in Life |
Controls |
This property gets a ControlCollection object that represents the child |
|
controls within the current control. |
DataBind() |
This method binds a data source to the invoked server control and all its |
|
child controls. |
EnableThemeing |
This property establishes if the control supports theme functionality. |
HasControls() |
This method determines if the server control contains any child controls. |
ID |
This property gets or sets the programmatic identifier assigned to the |
|
server control. |
Page |
This property gets a reference to the Page instance that contains the server |
|
control. |
Parent |
This property gets a reference to the server control’s parent control in the |
|
page control hierarchy. |
SkinID |
This property gets or sets the “skin” to apply to the control. Under ASP.NET |
|
2.0, it is now possible to establish a control’s overall look and feel on the fly |
|
via skins. |
Visible |
This property gets or sets a value that indicates whether a server control is |
|
rendered as UI element on the page. |
|
|
Enumerating Contained Controls
The first aspect of System.Web.UI.Control we will examine is the fact that all web controls (including Page itself) inherit a custom controls collection (accessed via the Controls property). Much like in a Windows Forms application, the Controls property provides access to a strongly typed collection of WebControl-derived types. Like any .NET collection, you have the ability to add, insert, and remove items dynamically at runtime.
While it is technically possible to directly add web controls directly to a Page-derived type, it is easier (and a wee bit safer) to make use of a Panel widget. The System.Web.UI.WebControls.Panel class represents a container of widgets that may or may not be visible to the end user (based on the value of its Visible and BorderStype properties).
To illustrate, create a new website named DynamicCtrls. Using the Visual Studio 2005 page designer, add a Panel type (named myPanel) that contains a TextBox, Button, and HyperLink widget named whatever you choose (be aware that the designer requires that you drag internal items within the UI of the Panel type). Once you have done so, the <form> element of your *.aspx file has been updated as so:
<asp:Panel ID="myPanel" runat="server" Height="50px" Width="125px"> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br /> <asp:Button ID="Button1" runat="server" Text="Button" /><br /> <asp:HyperLink ID="HyperLink1" runat="server">HyperLink </asp:HyperLink>
</asp:Panel>
Next, place a Label widget outside the scope of the Panel (named lblControlInfo) to hold the rendered output. Assume in the Page_Load() event you wish to obtain a list of all the controls contained within the Panel and assign the results to the Label type:

868CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ListControlsInPanel();
}
private void ListControlsInPanel()
{
string theInfo;
theInfo = String.Format("Has controls? {0}<br>", myPanel.HasControls());
foreach (Control c in myPanel.Controls)
{
if (c.GetType() != typeof(System.Web.UI.LiteralControl))
{
theInfo += "***************************<br>"; theInfo += String.Format("Control Name? {0}<br>",
c.ToString());
theInfo += String.Format("ID? {0}<br>", c.ID); theInfo += String.Format("Control Visible? {0}<br>",
c.Visible);
theInfo += String.Format("ViewState? {0}<br>", c.EnableViewState);
}
}
lblControlInfo.Text = theInfo;
}
}
Here, you iterate over each WebControl maintained on the Panel and perform a check to see if the current type is of type System.Web.UI.LiteralControl. This type is used to represent literal HTML tags and content (such as <br>, text literals, etc.). If you do not do this sanity check, you might be surprised to find a total of seven types in the scope of the Panel (given the *.aspx declaration seen previously). Assuming the type is not literal HTML content, you then print out some various statistics about the widget. Figure 23-20 shows the output.

CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS |
869 |
Figure 23-20. Enumerating contained widgets
Dynamically Adding (and Removing) Controls
Now, what if you wish to modify the contents of a Panel at runtime? The process should look very familiar to you, given your work with Windows Forms earlier in this text. Let’s update the current page to support an additional Button (named btnAddWidgets) that dynamically adds five new TextBox types to the Panel, and another Button that clears the Panel widget of all controls. The Click event handlers for each are shown here:
protected void btnAddWidgets_Click(object sender, EventArgs e)
{
for (int i = 0; i < 5; i++)
{
//Assign a name so we can get
//the text value out later
//using the HttpRequest.QueryString()
//method.
TextBox t = new TextBox();
t.ID = string.Format("newTextBox{0}", i); myPanel.Controls.Add(t); ListControlsInPanel();
}
}

870 CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS
protected void btnRemovePanelItems_Click(object sender, EventArgs e)
{
myPanel.Controls.Clear();
ListControlsInPanel();
}
Notice that you assign a unique ID to each TextBox (e.g., newTextBox1, newTextBox2, and so on) to obtain its contained text programmatically using the HttpRequest.Form collection (shown momentarily).
To obtain the values within these dynamically generated TextBoxes, update your UI with one additional Button and Label type. Within the Click event handler for the Button, loop over each item contained within the HttpRequest.NameValueCollection type (accessed via HttpRequest.Form) and concatenate the textual information to a locally scoped System.String. Once you have exhausted the collection, assign this string to the Text property of the new Label widget named lblTextBoxText:
protected void btnGetTextBoxValues_Click(object sender, System.EventArgs e)
{
string textBoxValues = "";
for(int i = 0; i < Request.Form.Count; i++)
{
textBoxValues +=
string.Format("<li>{0}</li><br>", Request.Form[i]);
}
lblTextBoxText.Text = textBoxValues;
}
When you run the application, you will find that you are able to view the content of each text box, including a rather long (unreadable) string. This string contains the view state for each widget on the page and will be examined later in the next chapter. Also, you will notice that once the request has been processed, the ten new text boxes disappear. Again, the reason has to do with the stateless nature of HTTP. If you wish to maintain these dynamically created TextBoxes between postbacks, you need to persist these objects using ASP.NET state programming techniques (also examined in the next chapter).
■Source Code The DynamicCtrls files are included under the Chapter 23 subdirectory.
Key Members of the
System.Web.UI.WebControls.WebControl Type
As you can tell, the Control type provides a number of non-GUI-related behaviors. On the other hand, the WebControl base class provides a graphical polymorphic interface to all web widgets, as suggested in Table 23-10.
Table 23-10. Properties of the WebControl Base Class
Properties |
Meaning in Life |
BackColor |
Gets or sets the background color of the web control |
BorderColor |
Gets or sets the border color of the web control |
BorderStyle |
Gets or sets the border style of the web control |
BorderWidth |
Gets or sets the border width of the web control |


872 CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS
The HTML controls are a collection of types that allow you to make use of traditional HTML controls on a Web Forms page. However, unlike raw HTML tags, HTML controls are OO entities that can be configured to run on the server and thus support server-side event handling. Unlike ASP.NET web controls, HTML controls are quite simplistic in nature and offer little functionality beyond standard HTML tags (HtmlButton, HtmlInputControl, HtmlTable, etc.).
The HTML controls provide a public interface that mimics standard HTML attributes. For example, to obtain the information within an input area, you make use of the Value property, rather than the web control–centric Text property. Given that the HTML controls are not as feature-rich as the ASP.NET web controls, I won’t make further mention of them in this text. If you wish to investigate these types, consult the .NET Framework 2.0 SDK documentation for further details.
Building a Simple ASP.NET 2.0 Website
Space does not permit me to walk through the details of each and every web control that ships with ASP.NET 2.0 (that would require a sizable book in and of itself). However, to illustrate the process of working with various ASP.NET web controls, the next task of this chapter is to construct a website that will demonstrate the use of the following techniques:
•Working with master pages
•Working with the Menu control
•Working with the GridView control
•Working with the Wizard control
As you work through this example, remember that Web Form controls encapsulate the process of generating corresponding HTML tags and follow a Windows Forms model. To begin, create a new ASP.NET web application named AspNetCarsSite.
Working with Master Pages
As I am sure you are aware, many websites provide a consistent look and feel across multiple pages (a common menu navigation system, common header and footer content, company logo, etc.). Under ASP.NET 1.x, developers made extensive use of UserControls and custom web controls to define web content that was to be used across multiple pages. While UserControls and custom web controls are still a very valid option under ASP.NET 2.0, we are now provided with the concept of master pages to address the same issue.
Simply put, a master page is little more than an ASP.NET page that takes a *.master file extension. On their own, master pages are not viewable from a client-side browser (in fact, the ASP.NET runtime will not server this flavor of web content). Rather, master pages define a common UI frame shared by all pages (or a subset of pages) in your site. As well, a *.master page defines various placeholder tags that contain additional content within an *.aspx file. The end result is a single, unified UI.
Insert a new master page into your website (via the WebSite Add New Item menu selection) and observe the initial definition:
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">

CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS |
873 |
<title>Untitled Page</title> </head>
<body>
<form id="form1" runat="server"> <div>
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> </asp:contentplaceholder>
</div>
</form>
</body>
</html>
The first point of interest is the new <%@Master%> directive. For the most part, this directive supports the same attributes as <%@Page%>. For example, notice how by default a master page makes use of a code-behind file (which is technically optional). Like Page types, a master page derives from
a specific base class, which in this case is MasterPage:
public partial class MasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
It is important to know that the attributes defined within the <%@Master%> directive do not “flow through” to the related *.aspx files. Thus, if you wish to make use of C# within your master page but author an associated *.aspx file in Visual Basic .NET, you may do so.
The other point of interest is the <asp:contentplaceholder> type. This region of a master page represents the UI widgets of the related *.aspx file, not the content of the master page itself. If you do intend to blend an *.aspx file within this region, the scope within the <asp:contentplaceholder> and </asp:contentplaceholder> tags will be empty. However, if you so choose, you are able to populate this area with various web controls that function as a default UI to use in the event that a given *.aspx file in the site does not supply specific content. For this example, assume that each *.aspx page in your site will indeed supply custom content.
■Note A *.master page may define as many content place holders as necessary. As well, a single *.master page may nest additional *.master pages.
As you would hope, you are able to build a common UI of a *.master file using the same Visual Studio 2005 designers used to build *.aspx files. For your site, you will add a descriptive Label (to serve as a common welcome message), an AdRotator control (which will randomly display one of two images), and a Menu control (to allow the user to navigate to other areas of the site).
Working with the Menu Control
ASP.NET 2.0 ships with several new web controls that allow you to handle site navigation: SiteMapPath, TreeView, and Menu. As you would expect, these web widgets can be configured in multiple ways. For example, each of these controls can dynamically generate its nodes via an external XML file or data source. For your Menu type, you will simply hard-code three values.
Using the page designer, select the Menu control, activate the inline editor (located at the upper left of the widget), and select the Edit Menu Items option. Add three root items named Home, Build a Car, and View Inventory. Before dismissing the dialog box, set the NavigateUrl property for each node to the following (yet to be constructed) pages: