Introducing the ASP.NET 2.0 GridView and DetailsView Controls

Stephen Walther
Microsoft Corporation

July 2004
Updated August 2005

Applies to:
Microsoft ASP.NET 2.0 framework
Microsoft Visual Studio 2005
ASP.NET GridView and DetailsView Controls

Summary: Display and edit database data and single database records with GridView and DetailsView, two new controls in the ASP.NET 2.0 framework. (21 printed pages)

Contents

Using the GridView Control
Sorting and Paging Records with the GridView Control
Client-Side Sorting and Paging
Editing with the GridView Control
Using the DetailsView Control
Conclusion

The ASP.NET 2.0 framework introduces two new controls for working with database data: the GridView control and the DetailsView control. You use the GridView control when working with a set of database records. The DetailsView control is used when working with individual records.

The GridView control is the successor to the DataGrid control. While Microsoft ASP.NET 2.0 still includes the DataGrid control, you are encouraged to take advantage of the new features of the GridView control.

The GridView control enables you to perform many of the same tasks as you would previously perform with the DataGrid control. The advantage of the GridView control is that, in many cases, you can perform these tasks without writing any code. The GridView control enables you to:

  • Display a set of database records.
  • Sort a set of database records.
  • Page through a set of database records.
  • Edit a set of database records.

In addition, unlike the DataGrid control, the GridView control enables you to sort and page through database records without requiring a postback to the server. The GridView control, optionally, uses client-side script to enable you to sort and page database records without performing a form post.

The DetailsView control is an entirely new control introduced with ASP.NET 2.0 that enables you to work with individual database records. You can use the DetailsView control on its own, to display or edit a single database record. When used in conjunction with the GridView control, you can use the DetailsView control to quickly build master/detail forms.

Using the GridView Control

The page in Listing 1 demonstrates the simplest use of the GridView control. The page displays the records from the Titles table in the Pubs database.

Listing 1. Displaying Database Records with the GridView Control

<html>

<head runat="server">

<title>Display GridView</title>

</head>

<body>

<form id="form1" runat="server">

<asp:GridView

DataSourceID="TitlesSource"

Runat="Server" />

<asp:SqlDataSource

ID="TitlesSource"

ConnectionString=

"Server=localhost;Database=pubs;Trusted_Connection=true"

SelectCommand="SELECT * FROM Titles"

Runat="Server" />

</form>

</body>

</html>

Figure 1 displays the rendered output of the GridView control in Listing 1. Notice that the page in Listing 1 does not contain any code. The GridView takes advantage of a DataSource control to retrieve the records that it displays. The GridView control is associated with the DataSource control through its DataSourceID property.

Figure 1. The GridView control

The ASP.NET 2.0 framework includes several DataSource controls that are designed to work with different data sources. The page in Listing 1 contains a SqlDataSource control. The SqlDataSource control represents records from any SQL database, including Microsoft SQL Server and Oracle databases. The ASP.NET 2.0 framework also includes an AccessDataSource control, which can be used to represent records from a Microsoft Access database table.

By default, a GridView control will automatically generate all of the columns that it displays. It will automatically create a column for each database column represented by its data source. If you need more control over the appearance of the GridView, you can set its AutoGenerateColumns property to the value false and explicitly list the fields that you want to display.

The GridView supports the following field types:

  • BoundField—Displays the value of a field as a string of text.
  • ButtonField—Displays a user specified button.
  • CheckboxField—Displays a checkbox when the value of field is a Boolean value.
  • CommandField—Automatically generates a command button such as an Edit, Update, or Cancel button.
  • HyperLinkField—Displays the value of a field as a hyperlink.
  • ImageField—Automatically displays an image when the value of a field represents an image.
  • TemplateField—Enables a user to customize the appearance of a column by supplying a template.

For example, the GridView in Listing 2 uses a BoundField and ImageField to display the last name and photo of each employee from the Employees table (located in the Northwind database).

Listing 2. Displaying Fields with a GridView

<html>

<head runat="server">

<title>Display Explicit Fields</title>

</head>

<body>

<form runat="server">

<asp:GridView

DataSourceID="ProductsSource"

AutoGenerateColumns="false"

Runat="Server">

<Columns>

<asp:BoundField

DataField="LastName"

NullDisplayText="no value" />

<asp:ImageField

DataField="Photo"

AlternateTextField="LastName"

AlternateTextFormatString="Photo of {0}" />

</Columns>

</asp:GridView>

<asp:SqlDataSource

ID="ProductsSource"

ConnectionString=

"Server=localhost;Database=Northwind;Trusted_Connection=true"

SelectCommand="SELECT * FROM Employees"

Runat="Server" />

</form>

</body>

</html>

Figure 2 displays the rendered output from the page in Listing 2. Notice that the BoundField is declared with a value for its NullDisplayText property. You can use the NullDisplayText property to specify the text displayed when a column has a null value.

Figure 2. GridView showing NullDisplayText

Notice also that the ImageField is declared with values for both its AlternateTextField and AlternateTextFormatString properties. These properties improve the accessibility of your page for visually impaired users.

Sorting and Paging Records with the GridView Control

Sorting and paging records with a GridView control could not be easier. When the GridView control's AllowSorting property has the value true, you can sort the columns in a GridView by clicking the header columns. When the AllowPaging property has the value true, you can page through sets of records in a GridView.

Listing 3 demonstrates how both the AllowSorting and AllowPaging properties can be used with the GridView (see Figure 3).

Listing 3. Sorting and Paging with a GridView

<html>

<head runat="server">

<title>Sorting and Paging a GridView</title>

</head>

<body>

<form id="form1" runat="server">

<asp:GridView

DataSourceID="TitlesSource"

AllowSorting="true"

AllowPaging="true"

Runat="Server" />

<asp:SqlDataSource

ID="TitlesSource"

ConnectionString=

"Server=localhost;Database=pubs;Trusted_Connection=true"

SelectCommand="SELECT * FROM Titles"

Runat="Server" />

</form>

</body>

</html>

Figure 3. GridView with Sorting and Paging enabled

The GridView control supports ascending and descending sorts. In other words, when you click a GridView column header multiple times, the column sort order is flipped back and forth between an ascending and descending sort.

By default, when AllowPaging has the value true, you can move between pages of records by clicking page numbers. You can modify the paging user interface by modifying the PagerSettings and PagerStyles properties. The GridView control supports the following interfaces:

  • NextPrevious—Displays a next and previous link.
  • NextPreviousFirstLast—Displays a next and previous link and a link to the first and last page.
  • Numeric—Displays page number links.
  • NumericFirstLast—Displays page number links and a link to the first and last page.

For example, the following GridView declaration renders a GridView with first, previous, next, and last links. Furthermore, the links are rendered as images (see Figure 4).

<asp:GridView

DataSourceID="TitlesSource"

AllowPaging="true"

PageSize="4"

Runat="Server">

<PagerSettings

Mode="NextPreviousFirstLast"

FirstPageImageUrl="First.gif"

PreviousPageImageUrl="Prev.gif"

NextPageImageUrl="Next.gif"

LastPageImageUrl="Last.gif" />

</asp:GridView>

Figure 4. Paging using images

Client-Side Sorting and Paging

The GridView control provides you with the option of sorting and paging records without requiring a form-post back to the Web server. In other words, you can re-render the contents of a GridView when sorting and paging, without needing to re-render the entire page.

You enable client paging and sorting by assigning the value true to the EnableSortingAndPagingCallback property. When this property has the value true, the GridView uses JavaScript to request an updated set of records from the Web server.

The page in Listing 4 demonstrates how to use the EnableSortingAndPagingCallback property.

Listing 4. Using Callbacks when Sorting and Paging

<html>

<head runat="server">

<title>Callback GridView</title>

</head>

<body>

<form runat="server">

<%=DateTime.Now %>

<asp:GridView

DataSourceID="TitlesSource"

EnableSortingAndPagingCallbacks="true"

AllowPaging="true"

AllowSorting="true"

Runat="Server" />

<asp:SqlDataSource

ID="TitlesSource"

ConnectionString=

"Server=localhost;Database=pubs;Trusted_Connection=true"

SelectCommand="SELECT * FROM Titles"

Runat="Server" />

</form>

</body>

</html>

The page in Listing 4 displays the current date and time, and the contents of the Titles database table. When you sort and page the records in the GridView, the time displayed by the page does not change. The time doesn't change because the page is not reloaded.

Behind the scenes, the GridView uses the Microsoft Internet Explorer XMLHTTPRequest object to communicate with the Web server. This object is supported by Internet Explorer version 5.0 and higher.

Editing with the GridView Control

You can enable users to edit the data displayed by a GridView by setting a single property: the AutoGenerateEditButton property. When the SqlDataSource control associated with the GridView has its UpdateCommand property set to a valid SQL UPDATE command, the database will be automatically updated.

For example, the page in Listing 5 enables you to update the contents of the Products database table (see Figure 5).

Listing 5. Editing with the GridView

<html>

<head runat="server">

<title>Edit GridView</title>

</head>

<body>

<form id="Form1" runat="server">

<asp:GridView

DataSourceID="ProductsSource"

AutoGenerateEditButton="true"

DataKeyNames="ProductID"

Runat="Server" />

<asp:SqlDataSource

ID="ProductsSource"

ConnectionString=

"Server=localhost;Database=Northwind;Trusted_Connection=true"

SelectCommand=

"SELECT ProductID,ProductName,Discontinued FROM Products"

UpdateCommand="Update Products

SET ProductName=@ProductName,Discontinued=@Discontinued

WHERE ProductID=@ProductID"

Runat="Server" />

</form>

</body>

</html>

Figure 5. Editing in the GridView

In most cases, the GridView can automatically determine the proper data types of the columns you are updating. In the case of the page in Listing 5, the value retrieved from the ProductID textbox is automatically converted to an integer, and the value of the Discontinued checkbox is automatically converted to a BIT before the UPDATE command is executed (You can check this by executing the SQL Profiler tool while executing the page).

There are certain data types that the GridView will not automatically convert, however, such as Decimal columns. If you need to use a Decimal column, you'll need to explicitly specify the column data type within the SqlDataSource. The page in Listing 6 illustrates how to do this.

Listing 6. Updating with Decimal Columns

<html>

<head runat="server">

<title>Edit GridView with Decimal</title>

</head>

<body>

<form id="Form1" runat="server">

<asp:GridView

DataSourceID="ProductsSource"

AutoGenerateEditButton="true"

DataKeyNames="ProductID"

Runat="Server" />

<asp:SqlDataSource

ID="ProductsSource"

ConnectionString=

"Server=localhost;Database=Northwind;Trusted_Connection=true"

SelectCommand=

"SELECT ProductID,ProductName,UnitPrice,Discontinued

FROM Products"

UpdateCommand=

"Update Products

SET ProductName=@ProductName, UnitPrice=@UnitPrice,

Discontinued=@Discontinued

WHERE ProductID=@ProductID"

Runat="Server" >

<UpdateParameters>

<asp:Parameter Name="UnitPrice" Type="Decimal" />

</UpdateParameters>

</asp:SqlDataSource>

</form>

</body>

</html>

Notice that the SqlDataSource control in Listing 6 now contains an <UpdateParameters> tag that lists the data type of the UnitPrice column. If you did not include this tag, the page would throw the SqlException "Disallowed implicit conversion from data type nvarchar to data type money."

One problem with both these samples of editing with the GridView is that they both do not contain any error handling code. If something goes wrong when executing the SQL UPDATE command, the page will explode in an ugly manner.

You can add error handling by creating an event handler for the GridView control's RowUpdated event. The page in Listing 7 demonstrates how you can gracefully handle SqlExceptions.

Listing 7. Editing with Error Handling

[Visual Basic .NET]

<%@ Page Language="vb" %>

<script runat="server">

Sub GridViewUpdated(ByVal s As Object, ByVal e As GridViewUpdatedEventArgs)

If Not e.Exception Is Nothing Then

lblError.Text = "Could not update row"

e.ExceptionHandled = True

End If

End Sub

</script>

<html>

<head runat="server">

<title>Edit GridView with Errors</title>

</head>

<body>

<form runat="server">

<asp:Label

ID="lblError"

ForeColor="Red"

EnableViewState="false"

Runat="Server" />

<asp:GridView

DataSourceID="ProductsSource"

OnRowUpdated="GridViewUpdated"

AutoGenerateEditButton="true"

DataKeyNames="ProductID"

Runat="Server" />

<asp:SqlDataSource

ID="ProductsSource"

ConnectionString=

"Server=localhost;Database=Northwind;Trusted_Connection=true"

SelectCommand=

"SELECT ProductID,ProductName,Discontinued FROM Products"

UpdateCommand="Update Products

SET ProductName=@ProductName,Discontinued=@Discontinued

WHERE ProductID=@ProductID"

Runat="Server" />

</form>

</body>

</html>

[C#]

<%@ Page Language="c#" %>

<script runat="server">

void GridViewUpdated(Object s, GridViewUpdatedEventArgs e)

{

if (e.Exception != null)

{

lblError.Text = "Could not update row";

e.ExceptionHandled = true;

}

}

</script>

<html>

<head runat="server">

<title>Edit GridView with Errors</title>

</head>

<body>

<form runat="server">

<asp:Label

ID="lblError"

ForeColor="Red"

EnableViewState="false"

Runat="Server" />

<asp:GridView

DataSourceID="ProductsSource"

OnRowUpdated="GridViewUpdated"

AutoGenerateEditButton="true"

DataKeyNames="ProductID"

Runat="Server" />

<asp:SqlDataSource

ID="ProductsSource"

ConnectionString=

"Server=localhost;Database=Northwind;Trusted_Connection=true"

SelectCommand=

"SELECT ProductID,ProductName,Discontinued FROM Products"

UpdateCommand="Update Products

SET ProductName=@ProductName,Discontinued=@Discontinued

WHERE ProductID=@ProductID"

Runat="Server" />

</form>

</body>

</html>

The GridViewUpdated method executes whenever a GridView row is finished being updated. The second parameter passed to this method—GridViewUpdatedEventArgs—has two properties that are useful for error handling. You use the Exception property to get any exception that was thrown when executing the SQL UPDATE command. The ExceptionHandled property enables you to indicate that you want to take care of handling the error. If you do not set this property to true, the exception will continue to be thrown.

Using the DetailsView Control

The DetailsView control enables you to work with individual database records. You can use this control to simply display a database record. You can also use the control to edit, delete, and insert new database records. Finally, when used with other controls, such as the GridView or DropDownList controls, you can use the DetailsView control to quickly create a Master/Detail form.

Displaying Database Records with the DetailsView Control

The simplest thing you can do with the DetailsView control is to display a single database record. The DetailsView control automatically displays labels and values for every column selected. Listing 8 illustrates how you can use the DetailsView control to display a single record from the Authors database table.

Listing 8. Displaying a Single Author

<html>

<head runat="server">

<title>Details View</title>

</head>

<body>

<form runat="server">

<asp:DetailsView

DataSourceID="AuthorsSource"

Runat="Server" />

<asp:SqlDataSource

ID="AuthorsSource"

ConnectionString=

"Server=localhost;Database=Pubs;Trusted_Connection=true"

SelectCommand=

"SELECT * FROM Authors WHERE au_id='172-32-1176'"

Runat="Server" />

</form>

</body>

</html>

In Listing 8, the DetailsView control is associated with a SqlDataSource control that selects an author with an ID of 172-32-1176. The page in Figure 6 is rendered.

Figure 6. DetailsView Control

Notice that the labels that are automatically generated by the DetailsView control correspond to the underlying database column names. Since the Authors database table includes field names such as au_lname and au_fname, these labels might appear strange.

If you want more control over the appearance of the DetailsView control, you can explicitly list the fields that you want the control to display. You can explicitly list fields by setting the control's AutoGenerateRows property to false and adding a <Fields> tag.

The DetailsView control supports the very same field types as the GridView control. The page in Listing 9 demonstrates how to explicitly specify fields and control the field labels.

Listing 9. Explicitly Listing Fields

<html>

<head runat="server">

<title>Details View</title>

</head>

<body>

<form id="Form1" runat="server">

<asp:DetailsView ID="DetailsView1"

DataSourceID="AuthorsSource"

AutoGenerateRows="false"

Runat="Server">

<Fields>

<asp:BoundField

DataField="au_id"

HeaderText="SS#:"

ReadOnly="true" />

<asp:BoundField

DataField="au_lname"

HeaderText="Last Name:" />

<asp:BoundField

DataField="au_fname"

HeaderText="Last Name:" />

</Fields>

</asp:DetailsView>

<asp:SqlDataSource

ID="AuthorsSource"

ConnectionString=

"Server=localhost;Database=Pubs;Trusted_Connection=true"

SelectCommand="SELECT * FROM Authors WHERE au_id='172-32-1176'"

Runat="Server" />

</form>

</body>

</html>

Thus far, we have seen how the DetailsView control can be used to display a single record. You can also use the DetailsView to navigate through multiple records. When you set the AllowPaging property to the value true, the DetailsView control automatically generates a user interface for moving between records. Listing 10 illustrates how you can use this property.

Listing 10. Navigating Records with the DetailsView Control

<html>