Pro ASP.NET 2.0 In CSharp 2005 (2005) [eng]
.pdf
338 C H A P T E R 1 0 ■ R I C H D ATA C O N T R O L S
<asp:BoundField DataField="Title" HeaderText="Title" /> <asp:BoundField DataField="City" HeaderText="City" />
</Columns>
</asp:GridView>
When you explicitly declare a bound field, you have the opportunity to set other properties. Table 10-2 lists these properties.
Table 10-2. BoundField Properties
Property |
Description |
DataField |
The name of the field (for a row) or property (for an object) of the |
|
data item that you want to display in this column. |
DataFormatString |
A format string that formats the field. This is useful for getting |
|
the right representation of numbers and dates. |
ApplyFormatInEditMode |
If true, the format string will be used to format the value even |
|
when it appears in a text box in edit mode. The default is false, |
|
which means only the underlying normal will be used (1143.02 |
|
instead of $1,143.02). |
FooterText, HeaderText, and |
Sets the text in the header and footer region of the grid, if this |
HeaderImageUrl |
grid has a heater (ShowHeader is true) and Footer (ShowFooter |
|
is true). The header is most commonly used for a descriptive |
|
label such as the field name, while the footer can contain a |
|
dynamically calculated value such as a summary (a technique |
|
demonstrated in the section “Summaries in the GridView” |
|
toward the end of this chapter). To show an image in the header |
|
instead of text, set the HeaderImageUrl property. |
ReadOnly |
If true, the value for this column can’t be changed in edit mode. |
|
No edit control will be provided. Primary key fields are often |
|
read-only. |
InsertVisible |
If false, the value for this column can’t be set in insert mode. If |
|
you want a column value to be set programmatically or based on |
|
a default value defined in the database, you can use this feature. |
Visible |
If false, the column won’t be visible in the page (and no HTML |
|
will be rendered for it). This property gives you a convenient way |
|
to programmatically hide or show specific columns, changing |
|
the overall view of the data. |
SortExpression |
An expression that can be appended to a query to perform a |
|
sort based on this column. Used in conjunction with sorting, as |
|
described in the “Sorting the GridView” section. |
HtmlEncode |
If true (the default), all text will be HTML encoded to prevent |
|
special characters from mangling the page. You could disable |
|
HTML encoding if you want to embed a working HTML tag (such |
|
as a hyperlink), but this approach isn’t safe. It’s always a better |
|
idea to use HTML encoding on all values and provide other |
|
functionality by reacting to GridView selection events. |
NullDisplayText |
The text that will be displayed for a null value. The default is an |
|
empty string, although you could change this to a hard-coded |
|
value, such as “(not specified).” |
ConvertEmptyStringToNull |
If this is true, before an edit is committed all empty strings will |
|
be converted to null values. |
ControlStyle, HeaderStyle, |
Configures the appearance for just this column, overriding the |
FooterStyle, and ItemStyle |
styles for the row. You’ll learn more about styles throughout this |
|
chapter. |
|
|
C H A P T E R 1 0 ■ R I C H D ATA C O N T R O L S |
339 |
If you don’t want to configure columns by hand, select the GridView, and click the ellipsis (…) next to the Columns property in the Properties window. You’ll see a Fields dialog box that lets you add, remove, and refine your columns (see Figure 10-1).
Figure 10-1. Configuring columns in Visual Studio
Now that you understand the underpinnings of the GridView, you’ve still only started to explore its higher-level features. In the following sections, you’ll tackle these topics:
•Formatting: How to format rows and data values
•Selecting: How to let users select a row in the GridView and respond accordingly
•Sorting: How to dynamically reorder the GridView in response to clicks on a column header
•Paging: How to divide a large result set into multiple pages of data, using both automatic and custom paging code
•Templates: How to take complete control of layout, formatting, and editing by defining templates
Formatting the GridView
Formatting consists of several related tasks. First, you want to ensure that dates, currencies, and other number values are presented in the appropriate way. You handle this job with the DataFormatString property. Next, you’ll want to apply the perfect mix of colors, fonts, borders, and alignment options to each aspect of the grid, from headers to data items. The GridView supports these features through styles. Finally, you can intercept events, examine row data, and apply formatting to specific data points programmatically. In the following sections, you’ll consider each of these techniques.
The GridView itself also exposes several formatting properties that are self-explanatory and aren’t covered here. These include GridLines (for adding or hiding table borders), CellPadding and CellSpacing (for controlling the overall spacing between cells), and Caption and CaptionAlign (for adding a title to the top of the grid).
340 C H A P T E R 1 0 ■ R I C H D ATA C O N T R O L S
■Tip Want to create a GridView that scrolls—inside a web page? It’s easy. Just place the GridView inside a Panel control, set the appropriate size for the panel, and set the Panel.Scrollbars to Auto, Vertical, or Both.
Formatting Fields
Each BoundField column provides a DataFormatString property that you can use to configure the appearance of numbers and dates using a format string.
Format strings are generally made up of a placeholder and format indicator, which are wrapped inside curly brackets. A typical format string looks something like this:
{0:C}
In this case, the 0 represents the value that will be formatted, and the letter indicates a predetermined format style. In this case, C means currency format, which formats a number as a dollar figure (so 3400.34 becomes $3,400.34). Here’s a column that uses this format string:
<asp:BoundField DataField="Price" HeaderText="Price" DataFormatString="{0:C}" />
Table 10-3 shows some of the other formatting options for numeric values.
Table 10-3. Numeric Format Strings
Type |
Format String |
Example |
Currency |
{0:C} |
$1,234.50 |
|
|
Brackets indicate negative values: ($1,234.50). |
|
|
Currency sign is locale-specific: (?1,234.50). |
Scientific (Exponential) |
{0:E} |
1.234.50E+004 |
Percentage |
{0:P} |
45.6% |
Fixed Decimal |
{0:F?} |
Depends on the number of decimal places you |
|
|
set. {0:F3} would be 123.400. {0:F0} would be 123. |
|
|
|
You can find other examples in the MSDN Help. For date or time values, there is also an extensive list. For example, if you want to write the BirthDate value in the format month/day/year (as in 12/30/05), you use the following column:
<asp:BoundField DataField="BirthDate" HeaderText="Birth Date" DataFormatString="{0:MM/dd/yy}" />
Table 10-4 shows some more examples.
Table 10-4. Time and Date Format Strings
Type |
Format String |
Example |
Short Date |
{0:d} |
M/d/yyyy |
|
|
(for example: 10/30/2005) |
Long Date |
{0:D} |
dddd, MMMM dd, yyyy |
|
|
(for example: Monday, January 30, 2005) |
Long Date and Short Time |
{0:f} |
dddd, MMMM dd, yyyy HH:mm aa |
|
|
(for example: Monday, January 30, 2005 |
|
|
10:00 AM) |
C H A P T E R 1 0 ■ R I C H D ATA C O N T R O L S |
341 |
Type |
Format String |
Example |
Long Date and Long Time |
{0:F} |
dddd, MMMM dd, yyyy HH:mm:ss aa |
|
|
(for example: Monday, January 30, 2005 |
|
|
10:00:23 AM) |
ISO Sortable Standard |
{0:s} |
yyyy-MM-dd HH:mm:ss |
|
|
(for example: 2005-01-30 10:00:23) |
Month and Day |
{0:M} |
MMMM dd |
|
|
(for example: January 30) |
General |
{0:G} |
M/d/yyyy HH:mm:ss aa (depends on locale- |
|
|
specific settings) |
|
|
(for example: 10/30/2002 10:00:23 AM) |
|
|
|
The format characters are not specific to the GridView. You can use them with other controls, with data-bound expressions in templates (as you’ll see later in this chapter), and as parameters for many methods. For example, the Decimal and DateTime types expose their own ToString() methods that accept a format string, allowing you to format values manually.
Styles
The GridView exposes a rich formatting model that’s based on styles. Altogether, you can set eight GridView styles, as described in Table 10-5.
Table 10-5. Numeric Format Strings
Style |
Description |
HeaderStyle |
Configures the appearance of the header row that contains column |
|
titles, if you’ve chosen to show it (if ShowHeader is true). |
RowStyle |
Configures the appearance of every data row. |
AlternatingRowStyle |
If set, applies additional formatting to every other row. This formatting |
|
acts in addition to the RowStyle formatting. For example, if you set a |
|
font using RowStyle, it is also applied to alternating rows, unless you |
|
explicitly set a different font through the AlternatingRowStyle. |
SelectedRowStyle |
Configures the appearance of the row that’s currently selected. |
|
This formatting acts in addition to the RowStyle formatting. |
EditRowStyle |
Configures the appearance of the row that’s in edit mode. |
|
This formatting acts in addition to the RowStyle formatting. |
EmptyDataRowStyle |
Configures the style that’s used for the single empty row in the special |
|
case where the bound data object contains no rows. |
FooterStyle |
Configures the appearance of the footer row at the bottom of the |
|
GridView, if you’ve chosen to show it (if ShowFooter is true). |
PagerStyle |
Configures the appearance of the row with the page links, if you’ve |
|
enabled paging (set AllowPaging to true). |
|
|
Styles are not simple single-value properties. Instead, each style exposes a Style object that includes properties for choosing colors (ForeColor and BackColor), adding borders (BorderColor, BorderStyle, and BorderWidth), sizing the row (Height and Width), aligning the row (HorizontalAlign and VerticalAlign), and configuring the appearance of text (Font and Wrap). These style properties allow you to refine almost every aspect of an item’s appearance. And if you don’t want to
342 C H A P T E R 1 0 ■ R I C H D ATA C O N T R O L S
hard-code all the appearance settings in the web page, you can set the CssClass property of the style object reference to a stylesheet class that’s defined in a linked stylesheet (see Chapter 15 for more about styles).
Defining Styles
When setting style properties, you can use two similar syntaxes (and you’ll see both of them in this chapter). First, you can use the object-walker syntax to indicate the extended style properties as tag attributes. Here’s an example:
<asp:GridView runat="server" ID="grid" ItemStyle-ForeColor="DarkBlue" ... />
...
</asp:GridView>
Alternatively, you can add nested tags, as shown here:
<asp:GridView runat="server" ID="grid" ...> <ItemStyle ForeColor="DarkBlue" ... />
...
</asp:GridView>
Both of these approaches are equivalent. However, you make one other decision when setting style properties. You can specify global style properties that affect every column in the grid (as in the previous examples), or you can define column-specific styles. To create a column-specific style, you need to add style attributes or a nested tag inside the appropriate column tag, as shown here:
<asp:GridView runat="server" ID="grid" ...> <Columns>
<asp:BoundField DataField="EmployeeID" HeaderText="ID" ItemStyle-Width="30px" />
...
</Columns>
</asp:GridView>
Or equivalently, you can use a nested tag:
<asp:GridView runat="server" ID="grid" ...> <Columns>
<asp:BoundField DataField="EmployeeID" HeaderText="ID"> <ItemStyle Width="30px">
</asp:BoundField>
...
</Columns>
</asp:GridView>
This technique is often used to define specific column widths. If you don’t define a specific column width, ASP.NET makes each column just wide enough to fit the data it contains (or, if wrapping is enabled, to fit the text without splitting a word over a line break). If values range in size, the width is determined by the largest value or the width of the column header, whichever is larger. However, if the grid is wide enough, you might want to expand a column so it doesn’t appear to be crowded against the adjacent columns. In this case, you need to explicitly define a larger width.
Here’s a fully formatted GridView tag:
<asp:GridView ID="GridView1" runat="server" DataSourceID="sourceEmployees" Font-Names="Verdana" Font-Size="X-Small" ForeColor="#333333" CellPadding="4" GridLines="None" AutoGenerateColumns="False">
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" /> <RowStyle BackColor="#FFFBD6" ForeColor="#333333" /> <AlternatingRowStyle BackColor="White" />
344 C H A P T E R 1 0 ■ R I C H D ATA C O N T R O L S
Configuring Styles with Visual Studio
There’s no reason to code style properties by hand in the GridView control tag, because the GridView provides rich design-time support. To set style properties, you can use the Properties window to modify the style properties. For example, to configure the font of the header, expand the HeaderStyle property to show the nested Font property, and set that. The only limitation of this approach is that it doesn’t allow you to set a style for individual columns—if you need that trick, you must first call up the Fields dialog box (shown in Figure 10-1) by editing the Columns property. Then, select the appropriate column, and set the style properties accordingly.
You can even set a combination of styles using a preset theme by clicking the Auto Format link in the GridView smart tag. Figure 10-3 shows the Auto Format dialog box with some of the preset styles you can choose. Select Remove Formatting to clear all the style settings.
Figure 10-3. Automatically formatting a GridView
Once you’ve chosen a theme, the style settings are inserted into your GridView tag, and you can tweak them by hand or by using the Properties window.
Formatting-Specific Values
The formatting you’ve learned so far isn’t that fine-grained. At its most specific, this formatting applies to a single column of values. But what if you want to change the formatting for a specific row, or even just a single cell?
The solution is to react to the GridView.RowCreated event. This event is raised when a part of the grid (the header, footer, or pager or a normal, alternate, or selected item) is being created. You can access the current row as a GridViewRow control. The GridViewRow.DataItem property provides the data object for the given row, and the GridViewRow.Cells collection allows you to retrieve the row content. You can use the GridViewRow to change colors and alignment, add or remove child controls, and so on.
The following example handles the RowCreated event and sets the colors according to the following rules:
C H A P T E R 1 0 ■ R I C H D ATA C O N T R O L S |
347 |
Figure 10-5. GridView selection
In the case of the GridView, the property you need to bind is SelectedIndex. However, this has one problem. SelectedIndex returns a zero-based index number representing where the row occurs in the grid. This isn’t the information you need to insert into the query that gets the related records. Instead, you need a key field from the corresponding row.
Fortunately, the GridView makes it easy to retrieve this information using the SelectedDataKeys property. To use this feature, you must set the GridView.DataKeyNames property, with a comma-separated list of one or more key fields. Each name you supply must match one of the properties of the bound object or one of the fields of the bound record.
Usually, you’ll have only one key field, as shown here:
<asp:GridView ID="gridEmployees" runat="server" DataSourceID="sourceEmployees" DataKeyNames="EmployeeID" ... >
Now you can bind the second data source to this field. Here’s an example that uses the EmployeeID in a join query to find all the matching records from the Territories table:
<asp:SqlDataSource ID="sourceRegions" runat="server" ConnectionString="<%$ ConnectionStrings:Northwind %>"
ProviderName="System.Data.SqlClient" SelectCommand="SELECT Employees.EmployeeID, Territories.TerritoryID, Territories.TerritoryDescription FROM Employees INNER JOIN EmployeeTerritories ON Employees.EmployeeID = EmployeeTerritories.EmployeeID
INNER JOIN Territories ON EmployeeTerritories.TerritoryID = Territories.TerritoryID WHERE (Employees.EmployeeID = @EmployeeID)" >
<SelectParameters>
<asp:ControlParameter ControlID="gridEmployees" Name="EmployeeID" PropertyName="SelectedDataKey.Values["EmployeeID"]" /> </SelectParameters>
</asp:SqlDataSource>
