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.
DetailsView
ControlIn 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.
DetailsView
ControlA DetailsView
control renders an HTML table that displays the contents of a single database record. The DetailsView
supports both declarative and programmatic databinding.
For example, the page in Listing 12.1 displays a record from the Movies database table, using declarative databinding (see Figure 12.1).
Figure 12.1. Displaying a movie record.
Listing 12.1. ShowDetailsView.aspx
In Listing 12.1, the SQL Select statement associated with the SqlDataSource
control retrieves the first movie from the Movies database table. The DetailsView
control is bound to the SqlDataSource
control through its DataSourceID
property.
You also can bind a DetailsView
control programmatically to a data source. The page in Listing 12.2 contains a DetailsView
bound to a collection of employees.
Listing 12.2. ShowEmployee.aspx
In Listing 12.2, an Employee
class is defined, which contains properties for the employee first name, last name, and retirement status. In the Page_Load()
method, a new employee is created and added to a generic collection. This collection is bound to the DetailsView
control.
DetailsView
ControlIf you need more control over the appearance of the DetailsView
, including the particular order in which columns display, you can use fields with the DetailsView
control, which 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 Chapter 11, “Using the GridView Control.”
The page in Listing 12.3 contains a DetailsView
control that contains three BoundFields
. The BoundFields
display the values of the Title, Director, and BoxOfficeTotals database columns (see Figure 12.2).
Figure 12.2. Using BoundFields
with the DetailsView
control.
Listing 12.3. ShowFields.aspx
The DetailsView
control has an AutoGenerateRows
property that has the value False
. When you specify fields for a DetailsView
control, you want to include this property so that the fields do not appear more than once.
Each of the BoundFields
in Listing 12.3 includes a HeaderText
attribute that is used to specify the label for the field. In addition, the BoundField
associated with the BoxOfficeTotals column includes a DataFormatString
property that formats the value of the column as a currency amount.
DetailsView
ControlThe 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, SqlDataSource
in Listing 12.4 does not return a record because no record in the Movies database table has an ID of -1.
Listing 12.4. ShowEmptyDataText.aspx
When you open the page in Listing 12.4, the contents of the EmptyDataText
property display.
If you need to display more complicated content when no results are returned, such as ASP.NET controls, you can specify an EmptyDataTemplate
. The page in Listing 12.5 illustrates how you can use the EmptyDataTemplate
to display complicated HTML content (see Figure 12.3).
Figure 12.3. Displaying content when no results are returned.
Listing 12.5. ShowEmptyDataTemplate.aspx
DetailsView
ControlYou can use the DetailsView
to page through a set of database records by enabling the DetailsView
control’s AllowPaging
property. The page in Listing 12.6 illustrates how you can page through the records in the Movies database table (see Figure 12.4).
Figure 12.4. Paging through records with the DetailsView
control.
Listing 12.6. ShowPaging.aspx
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 18, “Using the ObjectDataSource Control.”
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, Firefox, Safari, Chrome, and Opera.
The page in Listing 12.7 illustrates how you can use AJAX with the DetailsView
control.
Listing 12.7. ShowAJAX.aspx
The DetailsView
control in Listing 12.7 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, the page in Listing 12.7 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. UpdatePanel
is a more flexible method of doing Ajax.
You can customize the appearance of the paging interface by modifying the PagerSettings
property. For example, the DetailsView
control in Listing 12.8 displays first, previous, next, and last links instead of page numbers (see Figure 12.5).
Figure 12.5. Using PagerSettings
to customize the paging interface.
Listing 12.8. ShowPagerSettings.aspx
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
, 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.
If you need to customize the paging interface completely, you can use a template. For example, the page in Listing 12.9 displays a list of page numbers in a drop-down list control (see Figure 12.6).
Figure 12.6. Using a PagerTemplate
to customize the paging interface.
Listing 12.9. ShowPagerTemplate.aspx
After you open the page in Listing 12.9, you can select a record from the DropDownList
control and navigate to the record by clicking the Button
control.
DetailsView
ControlYou can use the DetailsView
control to update existing database records. To update an existing record, assign the value True to the DetailsView
control’s AutoGenerateEditButton
property, as illustrated in Listing 12.10 (see Figure 12.7).
Figure 12.7. Editing a record with the DetailsView
control.
Listing 12.10. ShowUpdate.aspx
When you open the page in Listing 12.10, the record appears in Read Only mode. You can click the Edit button to switch the DetailsView
into Edit mode and update the record.
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.
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, you can set the DetailsView
control’s DefaultMode
property to the value Edit
. For example, the page in Listing 12.11 contains a Master/Detail form. If you select any of the records in GridView
, you can edit the record with the DetailsView
control (see Figure 12.8).
Figure 12.8. Displaying a Master/Detail form with the DetailsView
control.
Listing 12.11. MasterDetailEdit.aspx
The DetailsView
control includes a DefaultMode
property set to the value Edit
. When you select a record, the record displays by DetailsView
in Edit mode by default.
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, you need to use templates with the DetailsView
control.
The page in Listing 12.12 uses TemplateFields
for the Title and BoxOfficeTotals columns. Both TemplateFields
contain a RequiredFieldValidator
. The BoxOfficeTotals column also includes a CompareValidator to check whether the value entered is a currency value (see Figure 12.9).
Figure 12.9. Using a template when editing with the DetailsView
control.
Listing 12.12. TemplateEdit.aspx
If you attempt to edit a record, and you do not provide a value for the Title or BoxOfficeTotals columns, a validation error displays. Also, if you enter anything other than a currency amount for the BoxOfficeTotals column, a validation error message displays.
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 2-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, 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
, the SqlDataSource
tracks both the original and modified versions of each column.
For example, the page in Listing 12.13 doesn’t enable a user to update a record when the original record has been modified after the user has opened the page.
Listing 12.13. Concurrency.aspx
Notice the contents of UpdateCommand
in Listing 12.13. The current values are compared against the original values for each database column when updating a record. If the current and original values don’t match, the record is not updated.
The SqlDataSource
has both its ConflictDetection
and OldValuesParameterFormat String
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 12.13, a message is displayed in a Label control when a record cannot be updated.
DetailsView
ControlYou can use the DetailsView
control to insert new records into a database table. For example, the page in Listing 12.14 enables you to insert a new record into the Movies database table.
Listing 12.14. ShowInsert.aspx
The DetailsView
control in Listing 12.14 includes an AutoGenerateInsertButton
property that has the value True
. This property automatically generates the user interface for inserting a new record.
After you open the page in Listing 12.14, you can click the New button to display a form for inserting a new record. When you click the Insert button, the SQL command represented by the SqlDataSource
control’s InsertCommand
property is executed.
If you want the DetailsView
control to display an insert form by default, you can assign the value Insert
to the DetailsView
control’s DefaultMode
property. This approach is illustrated by the page in Listing 12.15 (see Figure 12.10).
Figure 12.10. Inserting a record with the DetailsView
control.
Listing 12.15. ShowInsertMode.aspx
The page in Listing 12.15 contains both a GridView
and DetailsView
control. The DetailsView
control is hidden until you click the Insert Movie link. This link executes a JavaScript function named ShowInsert()
, which displays the DetailsView
control.
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.
DetailsView
ControlYou can delete records with the DetailsView
control by enabling its AutoGenerateDelete Button
property. The page in Listing 12.16 enables you to both insert and delete records in the Movies database table.
Listing 12.16. ShowDelete.aspx
When deleting records, you need to supply a value for the DetailsView
control’s DataKeyNames
property. A parameter named @Id
represents the value of the ID column in the DeleteCommand
property.
DetailsView
Control EventsThe 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.
Several of these events reflect similar events exposed by the DataSource
controls. For example, the SqlDataSource
control includes Inserting
and Inserted
events, which mirror the DetailsView
control’s ItemInserting
and ItemInserted
events.
The page in Listing 12.17 demonstrates how to use the ItemInserted
event to handle any errors that might be raised when inserting a new record into a database table (see Figure 12.11).
Figure 12.11. Handling database insert errors.
Listing 12.17. InsertErrors.aspx
If you attempt to insert a record without providing values for the Title or Director column, the error message contained in the Label control displays.
When you insert a record, the DetailsView
control raises the ItemInserted
event. The second parameter passed to the event handler for this method contains a property that exposes any exceptions raised when inserting the record. In Listing 12.17, if there is an exception, the exception is suppressed with the ExceptionHandled
property. Furthermore, the KeepInInsertMode
property prevents the DetailsView
from automatically switching out of Insert mode.
DetailsView
ControlThe 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 (CSS). 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.
The page in Listing 12.18 uses several of these properties to format a DetailsView
control (see Figure 12.12).
Figure 12.12. Formatting a DetailsView
control with CSS.
Listing 12.18. FormatDetailsView.aspx
FormView
ControlYou 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 use 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 FormView
is easier than adding validation controls to a DetailsView
control.
By default, the FormView
control renders an HTML table. It creates an HTML table that contains a single cell. In ASP.NET 4, you can disable this by setting the RenderOuterTable
property to False
. This enables you to style the output using CSS styles.
FormView
ControlYou can display a database record with the FormView
control by using an ItemTemplate
. For example, the page in Listing 12.19 displays a record from the Movies database table (see Figure 12.13).
Figure 12.13. Displaying a database record with the FormView
control.
Listing 12.19. ShowFormView.aspx
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.
FormView
ControlYou can allow users to navigate through a set of data items by allowing 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 12.20 automatically renders an additional row that contains buttons for navigating between data items.
Listing 12.20. ShowFormViewPaging.aspx
The FormView
in Listing 12.20 includes an AllowPaging
property 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
, you can page through the records in FormView
without performing a noticeable postback to the server.
This section describes user interface paging, which is not an efficient method to use when paging through large record sets because all the data must be loaded into memory. In Chapter 18, 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.
If you need to customize the appearance of the paging interface completely, you can create a PagerTemplate
. The page in Listing 12.21 uses the PagerTemplate
to create a custom paging interface. The PagerTemplate
displays the current page number. It also contains buttons for navigating to the previous and next page (see Figure 12.14).
Figure 12.14. Using a PagerTemplate
with the FormView
control.
Listing 12.21. ShowFormViewPagerTemplate.aspx
Each button contained in the PagerTemplate
has both a CommandName
and CommandArgument
property. The CommandName
is set to the value Page
. CommandArgument
specifies a particular type of paging operation.
You can use the following values for the CommandArgument
property:
• First
—Navigates to the first page.
• Last
—Navigates to the last page.
• Prev
—Navigates to the previous page.
• Next
—Navigates to the next page.
• number
—Navigates to a particular page number.
FormView
ControlYou can edit a database record with the FormView
control. For example, you can use the page in Listing 12.22 to edit any of the records in the Movies database table (see Figure 12.15).
Figure 12.15. Editing a record with the FormView
control.
Listing 12.22. ShowFormViewEditing.aspx
You should notice several things about the FormView
control in Listing 12.22. First, the FormView
control includes a DataKeyNames
property that contains the name of the primary key from the data source. You need to specify a primary key when editing records.
Next, the FormView
control’s ItemTemplate
includes a LinkButton
that looks like this:
<asp:LinkButton
id="lnkEdit"
Text="Edit Movie"
CommandName="Edit"
Runat="server" />
This LinkButton
includes a CommandName
property with the value Edit
. Clicking the link switches the FormView
control into Edit mode. You could use any other control here that supports the CommandName
property such as a Button
or ImageButton
control.
Next, the FormView
control includes an EditItemTemplate
. This template contains the form for editing the record. Each form field uses a two-way databinding expression. For example, the form field for editing the movie title looks like this:
<asp:TextBox
id="txtTitle"
Text='<%# Bind("Title") %>'
Runat="server" />
The Bind("Title")
method binds the Title column to the Text
property of the TextBox
control.
Finally, the EditItemTemplate
includes both a LinkButton
for updating the database record and a LinkButton
for canceling the update. The LinkButton
for updating the record looks like this:
<asp:LinkButton
id="lnkUpdate"
Text="Update Movie"
CommandName="Update"
Runat="server" />
This LinkButton
includes a CommandName
property, which has the value Update
. When you click this LinkButton
, the SQL statement represented by the SqlDataSource
control’s UpdateCommand
is executed.
If you want the FormView
control to be in Edit mode by default, you can assign the value Edit
to the FormView
control’s DefaultMode
property.
FormView
ControlYou can use the FormView
control to insert new records into a database table. For example, the page in Listing 12.23 enables you to insert a new movie record into the Movies database table.
Listing 12.23. ShowFormViewInserting.aspx
You should notice several things about the page in Listing 12.23. First, ItemTemplate
includes a LinkButton
control that looks like this:
<asp:LinkButton
id="lnkNew"
Text="New Movie"
CommandName="New"
Runat="server" />
When you click this LinkButton
control, the FormView
switches into Insert mode and displays the contents of the InsertTemplate
. The CommandName
property has the value New
.
The FormView
control includes InsertItemTemplate
that contains the form for inserting a new movie record. Each form field uses a two-way databinding expression. For example, the InTheaters CheckBox
looks like this:
<asp:CheckBox
id="chkInTheaters"
Text="In Theaters"
Checked='<%# Bind("InTheaters") %>'
Runat="server" />
The Bind("InTheaters")
method binds the value of the CheckBox
control’s Checked
property to the InTheaters
database column.
The InsertItemTemplate
contains a LinkButton
for inserting the record and a LinkButton
for canceling the insert operation. The LinkButton
for inserting a record looks like this:
<asp:LinkButton
id="lnkInsert"
Text="Insert Movie"
CommandName="Insert"
Runat="server" />
This LinkButton
control includes a CommandName
property that has the value Insert
. When you click the LinkButton
, the SQL command represented by the SqlDataSource
control’s InsertCommand
is executed.
You can place the FormView
control into Insert mode by default by assigning the value Insert
to the control’s DefaultMode
property.
FormView
ControlYou can use the FormView
control to delete database records. For example, the page in Listing 12.24 enables you to delete records from the Movies database table (see Figure 12.16).
Figure 12.16. Deleting a record with the FormView
control.
Listing 12.24. ShowFormViewDeleting.aspx
The FormView
control includes a DataKeyNames
property, which contains the name of the primary key column from the data source. When deleting records with the FormView
control, you need to indicate the primary key column.
Furthermore, the ItemTemplate
includes a LinkButton
for deleting a record. The LinkButton
looks like this:
This LinkButton
includes a CommandName
property that has the value Delete
. When you click the LinkButton
, the SQL command represented by the SqlDataSource
control’s DeleteCommand
property is executed.
Also, the LinkButton
includes an OnClientClick
property that calls the JavaScript confirm()
method to display a confirmation dialog box. This extra script prevents users from accidentally deleting database records.
In this chapter, you learned how to work with individual database records by using the DetailsView
and FormView
controls. You learned how to use both controls to display, page, edit, insert, and delete database records. You also learned how to format the appearance of both controls.