Home > Articles

Customizing the HTML Output

📄 Contents

  1. Specifying Display Properties in the DataGrid and DataList
  2. Customizing Data-Binding Output in Templates
  3. Summary
  4. On the Web
  • Print
  • + Share This
This chapter is from the book

In This Chapter

  • Specifying Display Properties in the DataGrid and DataList

  • Customizing Data-Binding Output in Templates

  • On the Web

We have used the data Web controls a number of times in code examples in the past two chapters. However, the appearance of the output has left a lot to be desired. Fortunately, making the DataGrid and DataList output more visually pleasing is quite simple, even for artistically challenged developers like myself!

As we will see in this chapter, both the DataGrid and DataList expose a number of properties that make specifying these details a breeze. Additionally, we'll look at how editors like Visual Studio .NET and the Web Matrix Project make specifying the appearance of the DataGrid and DataList as easy clicking a few buttons. (Note that the Repeater control does not contain any sort of stylistic properties; the developer is responsible for specifying any aesthetic properties directly in the HTML markup of the Repeater's templates.)

In this chapter we will also look at how to use built-in methods and custom functions to alter the output of data binding expressions in templates. For example, in Chapter 2's Listing 2.5, the String.Format() method is used within the data-binding expression of an ItemTemplate to have the number returned by Container.DataItem formatted with commas every three digits (line 17). (That is, 17711 [the 22nd Fibonacci number] is displayed as 17,711.) We'll examine how to use this approach to further customize the HTML emitted by data-bound values in a template.

By the end of this chapter, you will be able to generate professional-looking DataGrids and DataLists with just the setting of a few properties, or if you're using Visual Studio .NET or the Web Matrix Project, with simply the click of the mouse.

Specifying Display Properties in the DataGrid and DataList

Although the code examples we've studied thus far have been very useful in their structured display of data, they have been far from eye-pleasing. When viewing the screenshots of the code examples, did you ever think, "I wonder how I can change the font?" or "Wouldn't it look nicer if the cells in the DataGrid header were center-aligned?" If you did, you'll be pleased to learn that specifying such stylistic properties for the DataGrid and DataList is quite simple, as we will see in this section.

Recall that the DataGrid and DataList controls render into HTML table tags. When you think of a table, there are three levels to which stylistic formatting can be applied.

First, formatting can be applied to the entire table. This might include setting the font for the entire table to Verdana, or specifying the CellPadding or CellSpacing for the table.


CellPadding and CellSpacing are two stylistic properties of an HTML table. The CellPadding specifies the number of pixels between the cell's border and the cell's textual content. The CellSpacing specifies, in pixels, the spacing between neighboring table cells.

Second, formatting can be applied at the table row level. This row-level formatting can be specified for all rows in the table; for example, you might want all the rows to have a certain background color. Of course, setting this property for all the rows is synonymous with setting the property for the entire table.

You can also specify row-level formatting for just a subset of the rows. For example, you might opt for the rows' background to alternate between two colors. (That is, each even row might have a white background, and each odd row might have a light gray background.) Additionally, you can use row-level formatting to specify formatting for a single row. With the DataGrid and DataList, you can select a row and edit its data. You might want to use an alternative font for the row that is being edited. (We'll look at how to edit data in Chapter 9, "Editing the DataGrid Web Control.") In a similar vein, you might want to have a different style for the header and footer rows of the table.

The third level of stylistic formatting can be applied to the column level. Recall that the DataGrid has a Columns tag in which you can explicitly specify what columns should appear in the DataGrid control. Not surprisingly, you can apply stylistic settings to these columns. For example, you might want to have certain columns center- or right-aligned.

In this section, we will look at each of these levels of formatting separately and how to apply them programmatically. After this, we will look at specifying this formatting information using Visual Studio .NET and the Web Matrix Project. As we will see, specifying this property information with these tools is quite simple, requiring just a few clicks of the mouse.

Specifying Table-Level Display Properties

The DataGrid and DataList contain a number of table-level properties. Table 3.1 lists some of the more useful ones, along with a short description of each.

Table 3.1 Common Table-Level Properties for DataGrid and DataList




The background color of the table.


The color of the table border.


The border style. Must be set to a member of the BorderStyle enumeration.


The width of the border.


The cellpadding attribute of the table tag.


The cellspacing attribute of the table tag.


A cascading stylesheet class for the table that specifies style information.


Font information for the table. Specifies the font's name, size, and style options (bolded, italicized, underlined, and so on).


The foreground color of the table.


The height of the table, in either pixels or percentages.


The horizontal alignment of the table (Left, Right, or Center).


The width of the table, in either pixels or percentages.

These stylistic properties can be assigned programmatically, in the ASP.NET Web page's server-side script block or code-behind page, or declaratively, in the control's definition in the HTML section of the ASP.NET Web page.

Listing 3.1 illustrates the setting of a DataGrid's stylistic properties both programmatically and declaratively. Note that the majority of the contents of Listing 3.1 are identical to the code in Listing 2.1. The only differences are the DataGrid declaration on lines 30 and 31 and lines 23–25, where two display properties of the DataGrid are set programmatically.

Listing 3.1 A DataGrid's Display Properties Are Set Declaratively and Programmatically

 1: <%@ import Namespace="System.Data" %>
 2: <%@ import Namespace="System.Data.SqlClient" %>
 3: <script runat="server" language="VB">
 5:  Sub Page_Load(sender as Object, e as EventArgs)
 6:  '1. Create a connection
 7:  Const strConnString as String = "server=localhost;uid=sa;pwd=; database=pubs"
 8:  Dim objConn as New SqlConnection(strConnString)
10:  '2. Create a command object for the query
11:  Const strSQL as String = "SELECT * FROM authors"
12:  Dim objCmd as New SqlCommand(strSQL, objConn)
14:  objConn.Open() 'Open the connection
16:  'Finally, specify the DataSource and call DataBind()
17:  dgAuthors.DataSource = objCmd.ExecuteReader(CommandBehavior. CloseConnection)
18:  dgAuthors.DataBind()
20:  objConn.Close() 'Close the connection
23:  ' Set some DataGrid display properties programmatically
24:  dgAuthors.HorizontalAlign = HorizontalAlign.Center
25:  dgAuthors.Font.Bold = True
26:  End Sub
28: </script>
30: <asp:datagrid id="dgAuthors" runat="server" Font-Name="Verdana"
31:  Width="50%" />

Note that the DataGrid in Listing 3.1 has its display properties specified both programmatically (lines 24 and 25) and declaratively (lines 30 and 31). In the declarative section, we specify that the Verdana font should be used, and that the table should have a width of 50%. And in the Page_Load event handler, we specify that the table should be center-aligned and have a bold font.

One thing to note is the syntax used when specifying the font name. The Font property of the DataGrid (and DataList) is an instance of the System.Web.UI. WebControls.FontInfo class, which contains a number of properties, such as Name, Bold, Italic, Size, and so on. Therefore, we don't want to assign "Verdana" to the Font property, but instead to the Font.Name property. However, this dot notation, which we use when specifying a property programmatically (see line 25), does not work when setting a property declaratively. Rather, we have to replace all dots with dashes. Hence, instead of saying Font.Name = "Verdana" we do Font-Name="Verdana" (line 30).

On lines 24 and 25 we set two properties declaratively. The first is the HorizontalAlign property, which specifies that the table should be center-aligned. Note that the HorizontalAlign property needs to be assigned a value from the HorizontalAlign enumeration, so we assign it to HorizontalAlign.Center (line 24). If we were setting this property declaratively, however, we could omit the enumeration name, and just use HorizontalAlign="Center". On line 25 we specify that the contents of the table should be displayed in bold.


Had we used a DataList instead of a DataGrid in Listing 3.1, neither the programmatic nor declarative property settings would need to be changed in any way.

Figure 3.1 depicts a screenshot of Listing 3.1 when viewed through a browser.

Figure 3.1Figure 3.1  A centered table displayed in bold with a width of 50% is rendered.

Specifying Row-Level Display Properties

In the previous section, we noted a number of display properties that apply to the entire table rendered by the DataGrid or DataList. Most of these properties can also be applied at the row level, as we will see shortly.

To enable the developer to set row-level properties, the DataList and DataGrid provide a number of "ItemStyle" properties. These properties are called "ItemStyle" properties because they specify style information for the DataGridItem and DataListItem controls, which, as you'll recall from the previous chapter, are rendered as rows in the resulting table. The "ItemStyle" properties include the following:

  • ItemStyle

  • AlternatingItemStyle

  • EditItemStyle

  • SelectedItemStyle

  • HeaderStyle

  • FooterStyle

The last four "ItemStyle" properties—EditItemStyle, SelectedItemStyle, HeaderItemStyle, and FooterItemStyle—specify row-level styles for exactly one row. For example, the HeaderItemStyle specifies style information for the header row.

On the other hand, the ItemStyle and AlternatingItemStyle properties specify style settings for multiple rows. If the AlternatingItemStyle style is specified, it is applied to each alternating row in the table. If it is not specified, the ItemStyle is applied to all rows in the table.

Each of these "ItemStyle" properties is defined as a TableItemStyle instance. Table 3.2 shows the germane display properties of the TableItemStyle class.

Table 3.2 Common TableItemStyle Display Properties, Which Can Be Used to Specify Row-Level Display Properties




The background color of the table row.


The color of the table row's border.




The width of the border.


A cascading stylesheet class for the table that specifies style information.


Font information for the table row. Specifies the font's name, size, and style options (bolded, italicized, underlined, and so on).


The foreground color of the table row.


The height of the table row, in either pixels or percentages.


The horizontal alignment of the table row (Left, Right, or Center).


The vertical alignment of the table row (Top, Middle, or Bottom).


The width of the table row, in either pixels or percentages.


Specifies whether the contents in the cell should wrap—defaults to True.

Comparing Table 3.2 to Table 3.1, you can see that Table 3.2 does not include properties like CellPadding and CellSpacing, which are clearly table-level display settings. Furthermore, Table 3.1 does not contain the obvious row-level display settings, such as VerticalAlign and Wrap. The overlapping display properties, though, are common to both Tables 3.1 and 3.2.

As with the table-level display properties, the row-level display properties can be set both declaratively and programmatically. In addition to being set declaratively, the "ItemStyle" properties can also be set using embedded tags inside the DataGrid or DataList tag, as shown in Listing 3.2 on lines 9 and 10. The remaining source code has been omitted from Listing 3.2; essentially it is identical to the source code in Listing 3.1, with lines 22–25 from Listing 3.1 omitted. Figure 3.2 shows a screenshot of Listing 3.2 when viewed through a browser.

Listing 3.2 A DataList Is Used to Display Mailing Labels for the Various Authors

 1: <asp:datalist id="dlAuthorMailLabels" runat="server" Font-Name="Verdana"
 2:  HorizontalAlign="Center"
 3:  CellSpacing="10"
 5:  ItemStyle-Font-Size="8"
 7:  AlternatingItemStyle-BackColor="#dddddd">
 9:  <HeaderStyle HorizontalAlign="Center" Font-Bold="True"
10:     BackColor="Blue" ForeColor="White" />
12:  <HeaderTemplate>
13:  Mailing Labels
14:  </HeaderTemplate>
16:  <ItemTemplate>
17:  <%# DataBinder.Eval(Container.DataItem, "au_fname") %>
18:  <%# DataBinder.Eval(Container.DataItem, "au_lname") %>
19:  <br />
20:  <%# DataBinder.Eval(Container.DataItem, "address") %>
21:  <br />
22:  <%# DataBinder.Eval(Container.DataItem, "city") %>,
23:  <%# DataBinder.Eval(Container.DataItem, "state") %>
24:  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
25:  <%# DataBinder.Eval(Container.DataItem, "zip") %>
26:  </ItemTemplate>
27: </asp:datalist>

Figure 3.2Figure 3.2 The authors' contact information is presented as a list of mailing labels.

As mentioned earlier, one of the "ItemStyles" is the HeaderStyle, which specifies the display properties for the header. With the DataGrid, the header is automatically generated, containing the name of the columns. With the DataList, we have to supply our own header using the HeaderTemplate. In Listing 3.2, we simply give a title to our table in the HeaderTemplate (lines 12–14).


The header is the first row displayed in a data Web control, and typically contains a title for each column of data.

On lines 9 and 10, the HeaderStyle properties are set. Note that with the "ItemStyle" properties, we can use an alternative form of declaratively defining the properties. Simply put, we use a tag within the DataList (or DataGrid) tag. The tag name is the name of the "ItemStyle" property that we want to work with. We can then set the properties of that "ItemStyle" property by specifying them as attributes in the tag. For example, on line 10, we set the BackColor and ForeColor of the HeaderStyle to Blue and White, respectively.

On line 5 we set the ItemStyle's Font property's Size object to 8 point. On line 7 we set the AlternatingItemStyle's BackColor property to #dddddd, which is a light gray. This has the effect of alternating the background color between white and light gray for each alternating row in the DataList.

The ItemTemplate in Listing 3.2 (lines 17–25) is fairly straightforward, and is intended to display a list that can be used for mailing labels. First, the author's first and last names are shown, then a break (<br />), then the author's address, then another break, and finally the author's city, state, and zip code. Note that the &nbsp; is HTML markup to display nonbreaking whitespace. The five instances of &nbsp; (line 24) set the zip code five spaces from the end of the state in the city, state, and zip code line.

The code in Listing 3.2 does not demonstrate how to set "ItemStyle" properties programmatically. However, it is likely that your intuition can tell you the syntax. For example, to set the HeaderStyle's HorizontalAlign property to center, we could use

dlAuthorMailLabels.HeaderStyle.HorizontalAlign = HorizontalAlign.Center

To set the ItemStyle's Font's Size to 8 point, we could use

dlAuthorMailLabels.ItemStyle.Font.Size = FontUnit.Point(8)

A bit more care must be taken when setting the property of a data Web control programmatically versus setting it declaratively. When setting the font size declaratively, we simply use

<asp:DataList Font-Size="8pt" ... />

Notice that we essentially set the DataList's Font.Size property to the string "8pt". When setting the property programmatically, however, we just assign the Font.Size property to a string. That is, if we tried to set the DataList's Font.Size property to "8pt" using

dlAuthorMailLabels.ItemStyle.Font.Size = "8pt"

we'd get a compile-time error because of the mismatched types. That is, the Size property of the DataList's Font property expects a value of type System.Web.UI. WebControls.FontUnit, not of type string. That is why, in our earlier example, we set the DataList's Font.Size property to the FontUnit instance returned by the FontUnit.Point method:

dlAuthorMailLabels.ItemStyle.Font.Size = FontUnit.Point(8)

You might be wondering how I knew that the DataList's Font property's Size property was expecting a value of type FontUnit and not string. If you are given an expression like


and you need to determine the type of that expression, simply start with the leftmost object and work your way to the right end. That is, the leftmost object, dlAuthorMailLabels, is a DataList object. It has an ItemStyle property, which is the second leftmost object. This ItemStyle property is of type TableItemStyle, as we discussed eariler. The TableItemStyle class has a property Font, which is of type FontInfo. The FontInfo class has a property Size, which is of type FontUnit. Hence, the type of the entire expression


is FontUnit, meaning we must assign a value of type FontUnit to this expression.


Given this information, you might now be wondering why the Font.Size property can be assigned a string in the declarative form. That is, given what we just discussed, why doesn't


generate a type mismatch compile-time error? The reason is because, behind the scenes, the string "8pt." is being automatically converted into an appropriate FontUnit instance.

Specifying Column-Level Display Properties

As we've seen in previous chapters, the DataGrid control, by default, creates an HTML table with as many rows and columns as there are in the DataSource. However, by setting the AutoGenerateColumns property to False, you can explicitly specify what fields from the DataSource should be included in the DataGrid. Recall that to add a column to the DataGrid you must add an appropriate control in the DataGrid's Columns tag. That is, using our authors example, a DataGrid that had columns for the author's first and last name might look like this:

<asp:DataGrid runat="server" id="dgAuthorsNames">
 <asp:BoundColumn DataField="au_fname" HeaderText="First Name" />
 <asp:BoundColumn DataField="au_lname" HeaderText="Last Name" />

Recall that the following controls can be used within the Columns tag:

  • BoundColumn

  • TemplateColumn

  • EditColumn

  • ButtonColumn

  • HyperLinkColumn

Not surprisingly, you can specify various display properties for each of these column controls. In this chapter, we'll look at customizing the stylistic properties for the BoundColumn and TemplateColumn controls. For now we'll omit examination of EditColumn, ButtonColumn, and HyperLinkColumn, because we'll be seeing much more of these controls in later chapters.

Specifying Display Properties for the BoundColumn Control

The BoundColumn control contains three "ItemStyle" properties: ItemStyle, HeaderStyle, and FooterStyle. These "ItemStyle" properties indicate style information for the particular column. They contain the same set of display properties as the "ItemStyle" properties examined in the previous section.

In addition to these "ItemStyle" properties, the BoundColumn control contains a few other display properties. One we've seen in past examples is the HeaderText property, which specifies the text that should appear in the header of the column. This is useful if your DataSource has obscure field names (such as au_lname). A FooterText property is also included. The BoundColumn control also contains a HeaderImageUrl property, which, if specified, will place an img tag in the header.

The final display property for the BoundColumn control is the DataFormatString property. This string property specifies how the data in the column should be formatted. The syntax for the format string is a bit strange at first glance: {0:formatString}. This is the same syntax used for the String.Format() method, which we saw in a code example at the end of Chapter 2.

The String.Format() method accepts a string as its first parameter, and then accepts a variable number of parameters of type Object. The string parameter is a format string, which can contain a mix of normal text and format placeholders. The objects are the variables whose values we want to have plugged into the formatting placeholders.

For example, imagine that we have two variables of type float in C#, or of type Single in Visual Basic .NET, called basePrice and salesTax. The basePrice variable contains the sum of the prices for the products ordered by our customer, whereas the salesTax price is the sales tax on the customer's purchase; hence the total price due is the sum of these two variables.

Now, it would be nice to display a message indicating the customer's total, and how it was derived. We might want to have an output like: "Your total comes to $6.50. The base price was $5.75 and the sales tax was $0.75." To accomplish this, we could use the String.Format method like so:

String s = String.Empty;
String strFormat = "Your total comes to {0:c}. The base price was {1:c} " +
     "and the sales tax was {2:c}.";
s = String.Format(strFormat, basePrice+salesTax, basePrice, salesTax)

Note that the formatting placeholders ({0:c}, {1:c}, and {2:c}) indicate two things: the ordinal ranking of the variable whose value should be used when applying the formatting information, and the formatting to use. That is, {0:c} will apply a currency formatting to the 0th parameter (basePrice+salesTax)—note that c represents a currency formatting. {1:c} will apply a currency formatting to the 1st parameter, basePrice (really the 2nd one, because we start counting at 0). Finally, {2:c} will apply a currency formatting to the 2nd parameter, salesTax.

The DataStringFormat property of the BoundColumn control works in a similar fashion: Here you must specify the formatting placeholder. Keep in mind that the value that is inserted into the cell from the DataSource is the 0th parameter. Hence, if you have a field that stores, say, the price of each product, you can have it displayed as a currency by setting the BoundColumn control's DataFormatString to {0:c}. That is, the DataGrid might look like this:

 <asp:BoundColumn DataField="Name" HeaderText="Product Name" />
 <asp:BoundColumn DataField="Price" HeaderText="Price"
      DataFormatString="{0:c}" />

Clearly the c format string formats the specified variable value as a currency, but what other format strings are available? Table 3.3 lists a few of the more common ones, but there are far too many possibilities to list here. Instead, check out Microsoft's Formatting Overview page at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconformattingoverview.asp.

Table 3.3 Common Formatting Strings

Formatting String



Displays numeric values in currency format


Displays numeric values in decimal format and date/time variables in a short date pattern


Displays numeric values in hexadecimal format

Listing 3.3 illustrates setting a number of display properties for the BoundColumn controls. The source code is omitted from the listing, but it is the same as the source code from Listing 3.1, except that the SQL query on line 11 has been changed from SELECT * FROM authors to SELECT * FROM titles. Hence, the code in Listing 3.3 presents information about the various books in the database.

Listing 3.3 Column-Level Display Properties Can Be Set via the BoundColumn Control

 1: <asp:datagrid id="dgTitles" runat="server"
 2:  AutoGenerateColumns="False"
 3:  Font-Name="Verdana" Width="50%"
 4:  HorizontalAlign="Center" ItemStyle-Font-Size="9">
 6: <HeaderStyle BackColor="Navy" ForeColor="White"
 7:   HorizontalAlign="Center" Font-Bold="True" />
 9: <AlternatingItemStyle BackColor="#dddddd" />
11: <Columns>
12:  <asp:BoundColumn DataField="title" HeaderText="Title"
13:      ItemStyle-Width="70%" />
15:  <asp:BoundColumn DataField="price" HeaderText="Price"
16:      DataFormatString="{0:c}"
17:      ItemStyle-HorizontalAlign="Right"
18:      ItemStyle-Width="15%" />
20:  <asp:BoundColumn DataField="ytd_sales" HeaderText="Sales"
21:      DataFormatString="{0:#,###}"
22:      ItemStyle-HorizontalAlign="Right"
23:      ItemStyle-Width="15%" />
24: </Columns>
25: </asp:datagrid>

In Listing 3.3, there are three BoundColumns presenting key information from the titles table in the pubs database. The first BoundColumn (lines 12 and 13) simply shows the book's title. On line 13, the Width of the column is set to 70% via the ItemStyle property. Because we are working with column-level display properties, this width setting is relative to the table width, meaning the first column will be 70% of the total width of the table. Note that in line 3 we specified that the table should have a Width of 50% (this is relative to the Web page).

The second BoundColumn (lines 15–18) displays the price of the book. Line 16 sets the DataFormatString so that the value will be formatted as a currency. On line 17, the column values are specified to be right-aligned, and on line 18, the Width of the column is set to 15% (of the total width of the table).

The last BoundColumn (lines 20–23) displays the year-to-date sales. The DataFormatString on line 21 indicates that there should be a comma separating each of the three digits. The HorizontalAlign and Width properties on lines 22 and 23 mirror those on lines 17 and 18.

Figure 3.3 shows a screenshot of Listing 3.3 when viewed through a browser.

Figure 3.3Figure 3.3 Each column has specific stylistic properties set, such as formatting and alignment.

Specifying Display Properties for the TemplateColumn

Recall that the DataGrid can employ templates through the use of the TemplateColumn control. This control applies a template to a specific column in the DataGrid, as shown in the following code snippet:

<asp:DataGrid runat="server" id="dgTemplateColumnExample">
  <%# DataBinder.Eval(Container.DataItem, "SomeColumnName") %>

The display properties of the TemplateColumn are a subset of those of the BoundColumn. Specifically, the TemplateColumn's display properties include the following:

  • HeaderText

  • HeaderImageUrl

  • FooterText

  • ItemStyle

  • HeaderStyle

  • FooterStyle

With the TemplateColumn, you have more control over the display in the header and footer through the use of the HeaderTemplate and FooterTemplate.

Let's look at some code. Listing 3.4 contains a DataGrid that uses the same source code as Listing 3.3—it populates a SqlDataReader with the query SELECT * FROM titles and binds it to the DataGrid dgTitles. As with Listing 3.3, the source code has been removed from Listing 3.4 for brevity.

In Listing 3.4, a DataGrid with a BoundColumn control and a TemplateColumn control is created. The BoundColumn control displays the title of the book, and the TemplateColumn control displays information on the book's sales performance—essentially a simple sentence noting how many copies have been sold at what price. Three of the TemplateColumn control's display properties—HeaderText (line 15), and two ItemStyle properties (HorizontalAlign and Wrap on lines 16 and 17, respectively)—have been set declaratively.

Listing 3.4 The TemplateColumn Control Contains Display Properties Nearly Identical to That of the BoundColumn Control

 2:  AutoGenerateColumns="False"
 9: <AlternatingItemStyle BackColor="#dddddd" />
11: <Columns>
13:      ItemStyle-Width="70%" />
15:  <asp:TemplateColumn HeaderText="Sales Performance"
16:   ItemStyle-HorizontalAlign="Right"
17:   ItemStyle-Wrap="False">
18:  <ItemTemplate>
19:   <b><%# DataBinder.Eval(Container.DataItem, "ytd_sales", "{0:#,###}") %></b>
20:   copies sold at
21:   <b><%# DataBinder.Eval(Container.DataItem, "price", "{0:c}") %></b>
22:  </ItemTemplate>
23:  </asp:TemplateColumn>
24: </Columns>
25: </asp:datagrid>

Notice that we set the ItemStyle.Wrap property to False on line 17. This means that the text in this column will not wrap. Because the overall table width is defined to be 50% of the page (see the Width property on line 3), if we shrink the browser or lower the monitor resolution, the second column's text will remain all on one line, and the Title column's text will start wrapping.

Also notice that the DataBinder.Eval() method call on lines 19 and 21 uses three parameters instead of the two we've seen thus far. The third parameter specifies a format string (which follows the same guidelines and rules as the format string in the String.Format() method or the BoundColumn control's DataFormatString property. Hence, on lines 19 and 21 the value of the ytd_sales and price fields are formatted as currency (recall that the c applies a currency format).

Figure 3.4 shows a screenshot of the code in Listing 3.4 when viewed through a browser. Note that the rows that have NULLs for price and ytd_sales (The Psychology of Computer Cooking and Net Etiquette) are missing the numeric values for the sales number and sales price, but still have the string "copies sold at" present. Ideally, we don't want this string to display fields that have NULL values for these two database fields; perhaps we'd like to have a message like "Currently no copies of this book have been sold" appear instead. We'll see how to accomplish this later in this chapter, in the section "Customizing Data-Binding Output in Templates."

Figure 3.4Figure 3.4 A TemplateColumn is used to display the sales and price for each book.

Using Developer Tools to Specify Display Properties

Hopefully you've found that specifying display properties for the DataGrid and DataList controls is relatively easy. Unfortunately, for people like myself who are anything but artistic, getting an aesthetically pleasing DataGrid or DataList can still pose a bit of a challenge. I find that while setting the display properties might be easy enough, knowing what colors go well together and what fonts and font settings to use to create eye-pleasing output can be quite a challenge.

If your artistic skills are at all like mine, you'll find developer tools like Visual Studio .NET and the Web Matrix Project to be indispensable.

When creating ASP.NET Web pages with either of these tools, you can enter what is called the Design view, which presents a WYSIWYG view of the ASP.NET Web page called the Designer. From this Design view, you'll be able to drag and drop Web controls that are shown in the toolbox on the left.

After you drag a control onto the Designer you can click on the control, and a list of its properties should appear in the bottom right-hand corner. Figure 3.5 shows a screenshot of an ASP.NET Web page in the Web Matrix Project after a DataGrid has been dragged onto the Designer. You can specify various display properties from the properties window in the bottom right-hand corner.


Although the following screenshots show the Web Matrix Project in use, Visual Studio .NET provides an identical user experience when it comes to working with the Designer.

Figure 3.5Figure 3.5 You can set the DataGrid's display properties through the Properties window.

Although the Properties window is a nice way to quickly set display properties, a real gem for artistically challenged individuals is hidden in the Auto Format link at the bottom of the Properties window. After clicking on the Auto Format link, a dialog box appears with a listing of various style schemes and a preview of the style scheme (see Figure 3.6).

Figure 3.6Figure 3.6 The Auto Format dialog box allows you to quickly choose a style scheme for your DataGrid or DataList control.

After you have selected a style scheme and clicked the OK button, the Designer is updated to show the new look and feel of the style scheme you have chosen (see Figure 3.7). This also has the effect of updating the DataGrid (or DataList) control, automatically specifying the style properties. For example, Listing 3.5 contains the control markup automatically added to the ASP.NET Web page by simply dragging a DataGrid onto the Designer and opting for the Colorful 5 style scheme.

Figure 3.7Figure 3.7 The DataGrid's style has been updated with the format chosen in Figure 3.6.

Listing 3.5 The Auto Format Dialog Box Can Automatically Set Display Properties for Your DataGrid

1: <asp:DataGrid id="DataGrid1" runat="server" GridLines="None" BorderWidth="1px" BorderColor="Tan" 
BackColor="LightGoldenrodYellow" CellPadding="2" ForeColor="Black"> 2: <FooterStyle backcolor="Tan"></FooterStyle> 3: <HeaderStyle font-bold="True" backcolor="Tan"></HeaderStyle> 4: <PagerStyle horizontalalign="Center" forecolor="DarkSlateBlue" backcolor="PaleGoldenrod"></PagerStyle> 5: <SelectedItemStyle forecolor="GhostWhite" backcolor="DarkSlateBlue"> </SelectedItemStyle> 6: <AlternatingItemStyle backcolor="PaleGoldenrod"></AlternatingItemStyle> 7: </asp:DataGrid>


Line 4 in Listing 3.5 contains a PagerStyle tag, which sets properties for the PagerStyle property of the DataGrid. The PagerStyle property, which we've yet to discuss, is an "ItemStyle" property of the DataGrid. It is useful for specifying paging styles for DataGrids that support pagination. We'll be examining this property in more detail in Chapter 8, "Providing DataGrid Pagination."

A Note on How the Display Properties Are Rendered in the Browser

One of the nice things about ASP.NET Web controls is that they are adaptive to the user's browser. By that I mean the HTML markup emitted by an ASP.NET Web page's Web controls is dependent upon the browser being used to view the page. For example, the ASP.NET validation Web controls will emit client-side validation code if the user's browser is deemed to be an uplevel browser; if the browser is deemed to be a downlevel browser, then no such client-side code is emitted.

An uplevel browser is one that can support client-side JavaScript, HTML version 4.0, the Microsoft Document Object Model, and cascading stylesheets (CSS). You can define what constitutes an uplevel and a downlevel browser in the machine.config file; by default, Microsoft Internet Explorer 4.0 and later are considered uplevel, whereas all other browsers are considered downlevel.


Uplevel and downlevel status is only based upon the browser being used. That is, a user with Internet Explorer 6.0 would be detected as having an uplevel browser, even if the user has disabled JavaScript support in his browser.

The display properties for the DataGrid and DataList are rendered differently depending upon whether the user visiting the page is using an uplevel or a downlevel browser. If an uplevel browser is being used, the display properties are emitted as CSS. For example, in Listing 3.4, the header's style properties are set on lines 6 and 7. Specifically, the BackGround is set to Navy, and the ForeGround to White; the text is centered and made bold. When visiting with an uplevel browser, the header for the HTML table is rendered as the following:

<tr align="Center" style="color:White;background-color:Navy;font-weight:bold;">
  <td>Title</td><td>Sales Performance</td>

Note that the properties are all set in a style attribute of the tr tag.

However, if we visit this page with a downlevel browser (any browser other than Internet Explorer 4.0 or later), the following HTML is emitted:

<tr align="Center" bgcolor="Navy">
  <td><font face="Verdana" color="White"><b>Title</b></font></td>
<td><font face="Verdana" color="White"><b>Sales Performance</b></font></td>

Here the display properties are set using HTML instead of CSS.

If you are curious about the rendering differences between an uplevel and downlevel browser, you can do one of two things: view the same page with an uplevel browser (such as Internet Explorer 6.0) and a downlevel browser (such as Opera), comparing the HTML output that each browser receives; or programmatically specify how the controls on the page should be rendered by using the ClientTarget attribute in the @Page directive.

Using the ClientTarget attribute, you can have the controls on an ASP.NET Web page render as if the page were being visited by an uplevel or downlevel browser, independent of the actual browser being used. To specify that the controls should render as if being visited by an uplevel browser, use the following:

<%@ Page ClientTarget="uplevel" %>

Similarly, to force the controls to render as if they were being visited by a downlevel browser, use this:

<%@ Page ClientTarget="downlevel" %>

What About the Repeater Control?

The Repeater control does not have any display properties. Rather, to customize the HTML output of the Repeater, you must explicitly specify the HTML markup to use in the Repeater's templates. That is, if you want to have the Repeater output bold text, you have to specifically surround the text with the bold tag, or surround the text with a span tag whose style attribute contains a CSS rule to set the font-weight accordingly. (Realize that the DataList and DataGrid's templates can also be customized in this fashion.)

Of course, any time you encapsulate the appearance in HTML markup in a template, you are mixing code and content. Ideally, these two should be kept separate. By setting the appearance of the DataGrid and DataList via the display properties, it is much easier to make changes to the control or template markup later.

For example, imagine that you are using a DataGrid with a couple of TemplateColumns and you want the text in the TemplateColumn to be bold. Although you could simply add

<span style="font-weight:bold;">
 Template Markup

it would be cleaner to set the TemplateColumn's ItemStyle-Font-Bold property to True. If you later needed to change the TemplateColumn's output to italic instead of bold, changing the display property would be simpler than picking through the template markup. (Although it might not be much simpler in this trivial example, imagine that you have a large number of display properties set, and you want to change just one of them. Clearly, making such a change would be simpler using the display properties than if you use a large number of HTML tags to specify the style settings.)

Another advantage of using the display properties is that the HTML emitted is adaptive to the user's browser. If you had used the CSS markup shown previously to make the template's contents bold, a visitor using an older browser that does not support CSS would miss out on the intended visual experience. By using display properties, the correct markup is automatically chosen and sent to the user based upon her browser.

  • + Share This
  • 🔖 Save To Your Account