The DetailsView and FormView controls, the subject of this chapter, enable you to work
with a single data item at a time. Both controls enable you to display,
edit, insert, and delete data items such as database records.
Furthermore, both controls enable you to page forward and backward
through a set of data items.
The
difference between the two controls concerns the user interface that the
controls render. The DetailsView control always renders each field in a
separate HTML table row. The FormView control, on the other hand, uses a
template that enables you to completely customize the user interface
rendered by the control.
Using the DetailsView Control
In
this section, you learn how to use the DetailsView control when working
with database records. In particular, you learn how to display, page,
edit, insert, and delete database records with the DetailsView. You also
learn how to format the appearance of the DetailsView control.
Displaying Data with the DetailsView Control A DetailsView control
renders an HTML table that displays the contents of a single database
record. The DetailsView supports both declarative and programmatic
databinding.
Using Fields with the DetailsView Control
If
you need more control over the appearance of the DetailsView, including
the particular order in which columns are displayed, then you can use
fields with the DetailsView control. The DetailsView control supports
exactly the same fields as the GridView control:
- BoundField—Enables you to display the value of a data item as text.
- CheckBoxField—Enables you to display the value of a data item as a check box.
- CommandField—Enables you to display links for editing, deleting, and selecting rows.
- ButtonField—Enables you to display the value of a data item as a button (image button, link button, or push button).
- HyperLinkField—Enables you to display the value of a data item as a link.
- ImageField—Enables you to display the value of a data item as an image.
- TemplateField—Enables you to customize the appearance of a data item.
Another
option is to create custom fields for the DetailsView control. You can
create custom fields that work with the DetailsView control in exactly
the same way as you create custom fields that work with the GridView
control. Custom fields for the GridView control are discussed in the
final section of “Using the GridView Control.”
Displaying Empty Data with the DetailsView Control
The
DetailsView control includes two properties that you can use to display
a message when no results are returned from its data source. You can
use the EmptyDataText property to display an HTML string, or the
EmptyDataTemplate property to display more complicated content.
For
example, the SqlDataSource in Listing does not return a record because
no record in the Movies database table has an ID of -1.
When
you open the page in Listing, the contents of the EmptyDataText
property are displayed. If you need to display more complicated content
when no results are returned, such as ASP.NET controls, then you can
specify an EmptyDataTemplate. The page in Listing illustrates how you
can use the EmptyDataTemplate to display complicated HTML content.
Paging Through Data with the DetailsView Control
You
can use the DetailsView to page through a set of database records by
enabling the DetailsView control’s AllowPaging property. The page in
Listing illustrates how you can page through the records in the Movies
database table
In
this section, you learn how to take advantage of user interface paging
when paging through records with the DetailsView control. Although user
interface paging is convenient, it is not efficient. When working with
large sets of records, you should use data source paging. This option is
described in Chapter, “Using the ObjectDataSource Control.”
Paging with AJAX By
default, when you page through records with the DetailsView control,
the page is posted back to the server each and every time you click a
page number. As an alternative, you can take advantage of AJAX to page
through records. When you take advantage of AJAX, only the DetailsView
control and not the entire page is updated when you navigate to a new
page of records.
Ajax
(Asynchronous JavaScript and XML) enables you to retrieve content from a
web server without reloading the page. Ajax works with all modern
browsers including Microsoft Internet Explorer 6.0, Firefox 1.0, and
Opera 8.0.
The page in Listing illustrates how you can use AJAX with the DetailsView control.
Notice
that the DetailsView control in Listing is contained inside of an
UpdatePanel control. When you page through the records displayed by the
DetailsView control, only the content inside the UpdatePanel is updated.
Furthermore,
notice that the page in Listing displays the current time. The time is
not updated when you navigate to a new page of records. The time is not
updated because the entire page is not updated. When you navigate to a
new page, only the contents of the DetailsView are updated.
The
DetailsView control has an EnablePagingCallbacks property that also
enables Ajax. This is a holdover property from the ASP.NET 2.0
Framework. The UpdatePanel is a more flexible method of doing Ajax.
Customizing the Paging Interface
You
can customize the appearance of the paging interface by modifying the
PagerSettings property. For example, the DetailsView control in Listing
displays first, previous, next, and last links instead of page
numbers.
The PagerSettings class supports the following properties:
- FirstPageImageUrl—Enables you to display an image for the first page link.
- FirstPageText—Enables you to specify the text for the first page link.
- LastPageImageUrl—Enables you to display an image for the last page link.
- LastPageText—Enables you to specify the text for the last page link.
- Mode—Enables you to select a display mode for the pager user interface. Possible values are NextPrevious, NextPreviousFirstLast, Numeric, and NumericFirstLast.
- NextPageImageUrl—Enables you to specify the text for the next page link.
- NextPageText—Enables you to specify the text for the next page link.
- PageButtonCount—Enables you to specify the number of page number links to display.
- Position—Enables you to specify the position of the paging user interface. Possible values are Bottom, Top, and TopAndBottom.
- PreviousPageImageUrl—Enables you to display an image for the previous page link.
- PreviousPageText—Enables you to specify the text for the previous page link.
- Visible—Enables you to hide the paging user interface.
Updating Data with the DetailsView Control
You
can use the DetailsView control to update existing database records. In
order to update an existing record, assign the value True to the
DetailsView control’s AutoGenerateEditButton property as illustrated in
Listing.
When
you open the page in Listing, the record appears in Read Only mode. You
can click the Edit button to switch the DetailsView into Edit mode and
update the record. Notice that the DetailsView control includes a
DataKeyNames property and an AutoGenerateEditButton property. The
DataKeyNames property contains the name of the primary key column. The
AutoGenerateEditButton property automatically generates the user
interface for editing the record.
Notice that
the SqlDataSource control includes an UpdateCommand. The UpdateCommand
updates the Title, Director, and InTheaters database columns. If you
want the DetailsView control to initially appear in Edit mode, then you
can set the DetailsView control’s DefaultMode property to the value
Edit. For example, the page in Listing contains a Master/Detail form. If
you select any of the records in the GridView, you can edit the record
with the DetailsView control
Notice
that the DetailsView control includes a DefaultMode property that is
set to the value Edit. When you select a record, the record is displayed
by the DetailsView in Edit mode by default.
Using
Templates When Editing By default, you don’t get any validation when
editing records with the DetailsView control. In other words, there is
nothing to prevent you from attempting to submit a null value to a
database column that does not accept null values. If you need to perform
validation, then you need to use templates with the DetailsView
control.
If you
attempt to edit a record, and you do not provide a value for the Title
or BoxOfficeTotals columns, then a validation error is displayed. Also,
if you enter anything other than a currency amount for the
BoxOfficeTotals column, a validation error message is displayed.
Handling
Concurrency Issues What happens when two users edit the same record at
the same time? By default, the last user to update the database record
wins. In other words, one user can overwrite changes made by another
user.
Imagine
that Sally opens a page to edit a database record. After opening the
page, Sally leaves for her two-week vacation in Las Vegas. While Sally
is vacationing, Jim edits the same record and submits his changes. When
Sally returns from vacation, she submits her changes. Any modifications
that Jim makes are overwritten by Sally’s changes.
If you need
to prevent this scenario, then you can take advantage of optimistic
concurrency. The SqlDataSource control’s ConflictDetection property
supports the following two values:
- CompareAllValues
- OverwriteChanges
By default,
the ConflictDetection property has the value OverwriteChanges. If you
set this property to the value CompareAllValues, then the SqlDataSource
tracks both the original and modified versions of each column.
For
example, the page in Listing doesn’t allow a user to update a record
when the original record has been modified after the user has opened the
page.
The
SqlDataSource has both its ConflictDetection and
OldValuesParameterFormatString properties set. The
OldValuesParameterFormatString specifies the prefix added to the
parameters that represent the original field values.
If there is
a concurrency conflict, the e.AffectedRows property passed to the
Updated event handler will have the value 0. In Listing, a message is
displayed in a Label control when a record cannot be updated.
Inserting Data with the DetailsView Control
You
can use the DetailsView control to insert new records into a database
table. For example, the page in Listing enables you to insert a new
record into the Movies database table.
You can
hide a column when a DetailsView control is in Insert mode with the
BoundField control’s InsertVisible property. This property is useful,
for example, when you want to prevent users from inserting a value for
an identity column.
Deleting Data with the DetailsView Control
You
can delete records with the DetailsView control by enabling its
AutoGenerateDeleteButton property. The page in Listing enables you to
both insert and delete records in the Movies database table.
When
deleting records, you need to supply a value for the DetailsView
control’s DataKeyNames property. Notice that a parameter named @Id is
used to represent the value of the ID column in the DeleteCommand
property.
Working with DetailsView Control Events
The DetailsView control supports the following events:
- DataBinding—Raised immediately before the DetailsView control is bound to its data source.
- DataBound—Raised immediately after the DetailsView control is bound to its data source.
- ItemCommand—Raised when any control contained in the DetailsView raises an event (for example, when you click a button rendered by a ButtonField).
- ItemCreated—Raised when a DetailsView renders a data item.
- ItemDeleting—Raised immediately before a data item is deleted.
- ItemDeleted—Raised immediately after a data item is deleted.
- ItemInserting—Raised immediately before a data item is inserted.
- ItemInserted—Raised immediately after a data item is inserted.
- ItemUpdating—Raised immediately before a data item is updated.
- ItemUpdated—Raised immediately after a data item is updated.
- ModeChanging—Raised immediately before the DetailsView control’s mode is changed.
- ModeChanged—Raised immediately after the DetailsView control’s mode is changed.
- PageIndexChanging—Raised immediately before the current page is changed.
- PageIndexChanged—Raised immediately after the current page is changed
Formatting the DetailsView Control
The
DetailsView control includes an abundance of properties for formatting
the control. I recommend that you format the DetailsView control by
taking advantage of Cascading Style Sheets. All the following properties
expose a Style object that includes a CssClass property:
- CssClass—Enables you to associate a style sheet class with the DetailsView control.
- AlternatingRowStyle—Represents every other row rendered by the DetailsView control.
- CommandRowStyle—Represents the row that contains the edit buttons.
- EditRowStyle—Represents rows when the DetailsView control is in Edit mode.
- EmptyDataRowStyle—Represents the row displayed when the data source does not return any data items.
- FieldHeaderStyle—Represents the cell displayed for the field labels.
- FooterStyle—Represents the footer row.
- HeaderStyle—Represents the header row.
- InsertRowStyle—Represents rows when the DetailsView control is in Insert mode.
- PagerStyle—Represents the row or rows that display the paging user interface.
- RowStyle—Represents the rows displayed by the DetailsView control.
Furthermore, you can take advantage of the following properties when formatting a DetailsView control:
- GridLines—Enables you to specify the appearance of the rules that appear around the cells of the table rendered by a DetailsView control. Possible values are None, Horizontal, Vertical, and Both.
- HeaderText—Enables you to specify text that appears in the header of the DetailsView control.
- FooterText—Enables you to specify text that appears in the footer of the DetailsView control.
Using the FormView Control
You
can use the FormView control to do anything that you can do with the
DetailsView control. Just as you can with the DetailsView control, you
can use the FormView control to display, page, edit, insert, and delete
database records. However, unlike the DetailsView control, the FormView
control is entirely template driven. I end up using the FormView control
much more than the DetailsView control. The FormView control provides
you with more control over the layout of a form. Furthermore, adding
validation controls to a FormView is easier than adding validation
controls to a DetailsView control.
Unfortunately,
from a web standards perspective, the FormView control does, in fact,
render an HTML table. It creates an HTML table that contains a single
cell.
Displaying Data with the FormView Control
You
can display a database record with the FormView control by using an
ItemTemplate. For example, the page in Listing displays a record from
the Movies database table
Notice
that the FormView control’s DataSourceID property points to the
SqlDataSource control. The SqlDataSource control retrieves the first
record from the Movies database table. The ItemTemplate contains
databinding expressions that display the values of the Title, Director,
and BoxOfficeTotals columns. The Eval() method retrieves the values of
these columns. The databinding expression for the BoxOfficeTotals column
formats the value of the column as a currency amount.
Paging Through Data with the FormView Control
You
can enable users to navigate through a set of data items by enabling
paging. You can allow the FormView control to automatically render the
paging interface or you can use a PagerTemplate to customize the paging
interface.
The page in Listing automatically renders an additional row that contains buttons for navigating between data items.
Notice
that the FormView in Listing includes an AllowPaging property that is
assigned the value True. Adding this property generates the paging
interface automatically.
You can
enable Ajax paging for a FormView control in exactly the same way you
enable Ajax paging for a GridView or DetailsView control. If you wrap
the FormView control in an UpdatePanel, then you can page through the
records in the FormView without performing a noticeable postback to the
server.
This
section describes user interface paging. User interface paging is not an
efficient method to use when paging through large record sets because
all the data must be loaded into memory. In Chapter, “Using the
ObjectDataSource Control,” you learn how to implement data source
paging.
You can
customize the appearance of the automatically rendered paging interface
with the PagerSettings property, which exposes the PagerSettings class.
The PagerSettings class supports the following properties:
- FirstPageImageUrl—Enables you to display an image for the first page link.
- FirstPageText—Enables you to specify the text for the first page link.
- LastPageImageUrl—Enables you to display an image for the last page link.
- LastPageText—Enables you to specify the text for the last page link.
- Mode—Enables you to select a display mode for the pager user interface. Possible values are NextPrevious, NextPreviousFirstLast, Numeric, and NumericFirstLast.
- NextPageImageUrl—Enables you to specify the text for the next page link.
- NextPageText—Enables you to specify the text for the next page link.
- PageButtonCount—Enables you to specify the number of page number links to display.
- Position—Enables you to specify the position of the paging user interface. Possible values are Bottom, Top, and TopAndBottom.
- PreviousPageImageUrl—Enables you to display an image for the previous page link.
- PreviousPageText—Enables you to specify the text for the previous page link.
- Visible—Enables you to hide the paging user interface.
Editing Data with the FormView Control
You
can edit a database record with the FormView control. For example, you
can use the page in Listing to edit any of the records in the Movies
database table.
If you want
the FormView control to be in Edit mode by default, then you can assign
the value Edit to the FormView control’s DefaultMode property.
Inserting Data with the FormView Control
You
can use the FormView control to insert new records into a database
table. For example, the page in Listing enables you to insert a new
movie record into the Movies database table.
You can
place the FormView control into Insert mode by default by assigning the
value Insert to the control’s DefaultMode property.
Deleting Data with the FormView Control
You
can use the FormView control to delete database records. For example,
the page in Listing enables you to delete records from the Movies
database table.














