Editing Records - DetailsView

A DetailsView control includes features to perform basic editing of database records in the same manner as in a GridView. In addition, a DetailsView can include features for adding new records to a database. In the following example, a default DetailsView that displays books from the BooksDB.mdb database includes an "Edit" button for updating a book record. In addition, "Delete" and "New" buttons delete existing records from the database and display data entry fields for adding new records to the database.

Note that making actual changes to the BooksDB.mdb database is not permitted in these tutorials; however, all other functions work as expected.

Book Edit

 
BookIDDB111
BookTypeDatabase
BookTitleOracle Database
BookAuthorK. Loney
BookDescriptionGet thorough coverage of Oracle Database 10g from the most comprehensive reference available, published by Oracle Press. With in-depth details on all the new features, this powerhouse resource provides an overview of database architecture and Oracle Grid Computing technology, and covers SQL, SQL*Plus, PL/SQL, dynamic PL/SQL, object-oriented features, and Java programming in the Oracle environment. You'll also find valuable database administration and application development techniques, plus an alphabetical reference covering major Oracle commands, keywords, features, and functions, with cross-referencing of topics.
BookPrice$69.99
BookQty10
BookSale
Edit Delete New
12345678910...

Figure 9-13. Editing a database with a default DetailsView.

Complete coding for the AccessDataSource, DetailsView, and processing scripts for this application are shown below. You should recognize similarities to the setup for editing with a GridView.

<SCRIPT Runat="Server">

Sub Display_Updated_Msg (Src As Object, Args As DetailsViewUpdatedEventArgs)
  EditMSG.Text = "Record " & Args.Keys("BookID") & " updated"
End Sub

Sub Display_Deleted_Msg (Src As Object, Args As DetailsViewDeletedEventArgs)
  EditMSG.Text = "Record " & Args.Keys("BookID") & " deleted"
End Sub

Sub Display_Inserted_Msg (Src As Object, Args As DetailsViewInsertedEventArgs)
  EditMSG.Text = "Record " & Args.Values("BookID") & " added"
End Sub

</SCRIPT>

<form Runat="Server">

<asp:AccessDataSource id="BookSource" Runat="Server"
  DataFile="../Databases/BooksDB.mdb"
  
  SelectCommand="SELECT * FROM Books ORDER BY BookID"
  
  InsertCommand="INSERT INTO Books (BookID, BookType, BookTitle, BookAuthor,
                 BookDescription, BookPrice, BookQty, BookSale) 
                 VALUES (@BookID, @BookType, @BookTitle, @BookAuthor,
                 BookDescription=@BookDescription, @BookPrice, @BookQty, 
                 @BookSale)"
  
  UpdateCommand="UPDATE Books SET BookType=@BookType, BookTitle=@BookTitle,
                 BookAuthor=@BookAuthor, BookDescription=@BookDescription,
                 BookPrice=@BookPrice, BookQty=@BookQty, BookSale=@BookSale 
                 WHERE BookID=@BookID"
  
  DeleteCommand="DELETE FROM Books WHERE BookID = @BookID"
/>

<h3>Book Edit</h3>

<asp:Label id="EditMSG" ForeColor="Red" Runat="Server"
EnableViewState="False" Text=" "/>

<asp:DetailsView id="EditView" DataSourceID="BookSource" Runat="Server"
  DataKeyNames="BookID"
  AutoGenerateEditButton="True"
  AutoGenerateDeleteButton="True"
  AutoGenerateInsertButton="True"
  OnItemUpdated="Display_Updated_Msg"
  OnItemDeleted="Display_Deleted_Msg"
  OnItemInserted="Display_Inserted_Msg"
  AllowPaging="True"
  RowStyle-Font-Size="10pt"
  RowStyle-VerticalAlign="Top"
/>
Listing 9-19. Code for default DetailsView with editing.

"Edit," "Delete," and "Insert" buttons are added to the DetailsView by coding AutoGenerateEditButton="True", AutoGenerateDeleteButton="True", and AutoGenerateInsertButton="True" properties. Also, the DataKeyNames property gives the database field (BookID) that serves as the unique identifier, the primary key, for the records. In this example, the recordset is paged.

When all editing functions are implemented for a DetailsView, its AccessDataSource requires a SelectCommand (SELECT statement) to select records for display in the DetailsView, a parameterized UpdateCommand (UPDATE statement) to rewrite changes to the database, a parameterized InsertCommand (INSERT statement) to add records to the database, and a parameterized DeleteCommand (DELETE statement) to delete records from the database.

You should be familiar with formatting for the UPDATE and DELETE statements since they are similar to those used for editing a GridView. The parameterized INSERT statement uses similar formatting. Database fields are associated with edit box parameters to write a new record with new data values to the database. In this case, the primary key field also is written as part of the record; that is, field BookID is associated with parameter @BookID in the matching list of INSERT fields and field VALUES.

Editing Events and Event Handlers

Update, insert, and delete buttons carry out their tasks automatically unless scripts are provided to intercept processing. Subprograms can be called by these buttons by coding event handlers in the DetailsView. The following events can be scripted.

Event Event Handler Signature Description
ItemInserting OnItemInserting DetailsViewInsertEventArgs A new record is being added to the data source but has not yet been written.
ItemInserted OnItemInserted DetailsViewInsertedEventArgs A new record has been written to the data source.
ItemUpdating OnItemUpdating DetailsViewUpdateEventArgs A record is being updated but has not yet been rewritten to the data source.
ItemUpdated OnItemUpdated DetailsViewUpdatedEventArgs An updated record has been rewritten to the data source.
ItemDeleting OnItemDeleting DetailsViewDeleteEventArgs A record is being deleted from the data source but has not yet been deleted.
ItemDeleted OnItemDeleted DetailsViewDeletedEventArgs A record has been deleted from the data source.
Figure 9-14. DetailsView event handlers and subprogram arguments.

In the current example, OnItemUpdated, OnItemDeleted, and OnItemInserted event handlers are added to the DetailsView in order to display editing messages associated with completion of these events. As in the case with a GridView, subprograms are exposed to event properties. The list of accessible properties for the six events of DetailsView editing are shown below. Most of these should be familiar from identical properties for the GridView.

--DetailsViewInsertEventArgs Properties--

argument.Values("field")
argument.Cancel="False|True"

--DetailsViewInsertedEventArgs Properties--

argument.Values("field")
argument.AffectedRows
argument.KeepInInsertMode="False|True"

--DetailsViewUpdateEventArgs Properties--

argument.OldValues("field")
argument.NewValues("field")
argument.Keys("field")
argument.Cancel="False|True"

--DetailsViewUpdatedEventArgs Properties--

argument.OldValues("field")
argument.NewValues("field")
argument.Keys("field")
argument.AffectedRows
argument.KeepInEditMode="False|True"

--DetailsViewDeleteEventArgs Properties--

argument.Values("field")
argument.Keys("field")
argument.Cancel="False|True"

--DetailsViewDeletedEventArgs Properties--

argument.Values("field")
argument.Keys("field")
argument.AffectedRows
Figure 9-15. General formats for referencing DetailsView event properties.

Subprograms for the example DetailsView report the key field for updated and deleted records—Args.Keys("BookID")—and the key value for an inserted record—Args.Values("BookID"). In this latter case, the BookID field is not a key field until after it has been inserted into the database. Therefore, it is just another field value until after insertion.

The <asp:CommandField> Control

Default link buttons are supplied for editing functions by specifying "True" for the AutoGenerateInsertButton, AutoGenerateUpdateButton, and AutoGenerateDeleteButton properties of the DetailsView. These buttons appear as text links at the bottom of the DetailsView. An alternative is to set these properties to False (the default value) and to define an <asp:CommandField> to display selected buttons at selected locations in selected styles.

The following DetailsView incorporates a CommandField to override default editing buttons. The remaining data fields take on default appearances as in the previous DetailsView.

Book Edit

 
BookIDDB111
BookTypeDatabase
BookTitleOracle Database
BookAuthorK. Loney
BookDescriptionGet thorough coverage of Oracle Database 10g from the most comprehensive reference available, published by Oracle Press. With in-depth details on all the new features, this powerhouse resource provides an overview of database architecture and Oracle Grid Computing technology, and covers SQL, SQL*Plus, PL/SQL, dynamic PL/SQL, object-oriented features, and Java programming in the Oracle environment. You'll also find valuable database administration and application development techniques, plus an alphabetical reference covering major Oracle commands, keywords, features, and functions, with cross-referencing of topics.
BookPrice$69.99
BookQty10
BookSale
   
12345678910...

Figure 9-16. A DetailsView with CommandField buttons.

The general format for a CommandField, which appears inside the <Fields> tag of the DetailsView, is shown below along with associated properties for the DetailsView and CommandField.

<asp:DetailsView
  AutoGenerateInsertButton="False|True"
  AutoGenerateEditButton="False|True"
  AutoGenerateDeleteButton="False|True"
  OnItemDeleting="subprogram"
  OnItemDeleted="subprogram"
  OnItemInserting="subprogram"
  OnItemInserted="subprogram"
  OnItemUpdating="subprogram"
  OnItemUpdated="subprogram"
  
  InsertRowStyle-property="value"...
  EditRowStyle-property="value"...
  DeleteRowStyle-property="value"...
  ...
>
	
  <Fields>
	
    <asp:CommandField
      ButtonType="Link|Button"
      ShowCancelButton="False|True"
      ShowDeleteButton="False|True"
      ShowEditButton="False|True"
      ShowInsertButton="False|True"
      ShowHeader="False|True"
      CancelText="string"
      DeleteText="string"
      EditText="string"
      InsertText="string"
      HeaderText="string"
      NewText="string"
      UpdateText="string"
 		
      HeaderStyle-property="value"...
      ItemStyle-property="value"...
      ControlStyle-property="value"...
    />
    ...
	
  </Fields>
	
</asp:DetailsView>
Figure 9-17. General format for CommandField row type of DetailsView control.

An <asp:CommandField> control appears in the row of the DetailsView wherever it is coded. If editable rows are automatically generated as in the current example, the CommandField appears at the bottom. It defines a row where one or more editing buttons can be placed by coding ShowInsertButton="True," ShowEditButton="True," and/or ShowDeleteButton="True" properties for the DetailsView. By default, the buttons are displayed as text links unless ButtonType="Button" is coded. Standard text labels are displayed for the buttons; these can be overridden with CancelText, DeleteText, EditText, InsertText, NewText, and UpdateText properties with different labels for the buttons. Style settings for buttons are given by coding ControlStyle properties for the CommandField.

For updating a displayed record, an "Edit" button is displayed. When clicked, a second set of "Update" and "Cancel" buttons appears to rewrite changes to the database or to cancel the task. For adding a new record to the database, a "New" button is displayed. When clicked, a second set of "Insert" and "Cancel" buttons appears and all fields are converted into data-entry types. Clicking the "Insert" button adds the new record to the database. For deleting a record, a "Delete" button is displayed. When clicked, the record is immediately deleted from the database.

Shown below is code for the example DetailsView with CommandField buttons displayed.

<asp:DetailsView id="EditView" DataSourceID="BookSource" Runat="Server"
  DataKeyNames="BookID"
  AutoGenerateEditButton="False"
  AutoGenerateDeleteButton="False"
  AutoGenerateInsertButton="False"
  OnItemUpdated="Display_Updated_Msg"
  OnItemDeleted="Display_Deleted_Msg"
  OnItemInserted="Display_Inserted_Msg"
  AllowPaging="True"
  RowStyle-Font-Size="10pt"
	RowStyle-VerticalAlign="Top">
	
  <Fields>
	
  <asp:CommandField
    ButtonType="Button"
    HeaderStyle-BackColor="#E0E0E0"
    ItemStyle-BackColor="#E0E0E0"
    ShowHeader="True"
    ShowInsertButton="True"
    ShowEditButton="True"
    ShowDeleteButton="True"
    ControlStyle-Font-Size="9pt"
    ControlStyle-Width="50px"/>

  </Fields>

</asp:DetailsView>
Listing 9-20. Code for DetailsView with CommandField to display edit buttons.

Incidentally, a CommandField can be supplied for a GridView. However, since a GridView does not support new record insertions, ShowInsertButton should be set to False so that it does not display and leave the false impression that the “Insert” button is functional.

Formatted DetailsView Editing

The basic DetailsView can be expanded with bound columns for more control over display of data and editing fields. The following formatted DetailsView provides the same functionality as previous examples with the addition of validation of entered data identical to the processing done through the previous GridView control.

Book Edit

 
 
ID: DB111
Type: Database
Title: Oracle Database
Author: K. Loney
Description:
Get thorough coverage of Oracle Database 10g from the most comprehensive reference available, published by Oracle Press. With in-depth details on all the new features, this powerhouse resource provides an overview of database architecture and Oracle Grid Computing technology, and covers SQL, SQL*Plus, PL/SQL, dynamic PL/SQL, object-oriented features, and Java programming in the Oracle environment. You'll also find valuable database administration and application development techniques, plus an alphabetical reference covering major Oracle commands, keywords, features, and functions, with cross-referencing of topics.
Price: $69.99
Qty: 10
Sale:
12345678910...

Figure 9-18. DetailsView editing with bound columns and data validation.

Coding the DetailsView

Coding for the DetailsView and its AccessDataSource for the above example is shown below. The AccessDataSource is identical to the previous example. A second AccessDataSource supplies values for DropDownLists of book types during updates and additions. A default DetailsView is overridden with bound data fields and template fields. Also, neither auto-generated buttons nor a CommandField is used to display editing buttons. Instead, editing buttons are coded as standard Button controls inside a TemplateField.

<asp:AccessDataSource id="BookSource" Runat="Server"
  DataFile="../Databases/BooksDB.mdb"
  
  SelectCommand="SELECT * FROM Books ORDER BY BookID"
  
  InsertCommand="INSERT INTO Books (BookID, BookType, BookTitle, BookAuthor,
                 BookDescription, BookPrice, BookQty, BookSale) VALUES
                 (@BookID, @BookType, @BookTitle, @BookAuthor,
                 BookDescription=@BookDescription, @BookPrice, @BookQty, 
                 @BookSale)"
  
  UpdateCommand="UPDATE Books SET BookType=@BookType, BookTitle=@BookTitle,
                 BookAuthor=@BookAuthor, BookDescription=@BookDescription,
                 BookPrice=@BookPrice, BookQty=@BookQty, BookSale=@BookSale 
                 WHERE BookID=@BookID"
  
  DeleteCommand="DELETE FROM Books WHERE BookID = @BookID"
/>

<asp:AccessDataSource id="TypeSource" Runat="Server"
  DataFile="../Databases/BooksDB.mdb"
  SelectCommand="SELECT DISTINCT BookType FROM Books ORDER BY BookType"/>

<h3>Book Edit</h3>

<asp:Label id="EditMSG" Text=" " ForeColor="Red" Runat="Server"
EnableViewState="False"/>

<asp:DetailsView id="EditView" DataSourceID="BookSource" Runat="Server"
  DataKeyNames="BookID"
  AutoGenerateRows="False"
  AutoGenerateInsertButton="False"
  AutoGenerateEditButton="False"
  AutoGenerateDeleteButton="False"
  OnItemInserting="Validate_Insert_Data"
  OnItemInserted="Display_Insert_Msg"
  OnItemUpdating="Validate_Update_Data"
  OnItemUpdated="Display_Update_Msg"
  OnItemDeleted="Display_Delete_Msg"
  AllowPaging="True"
  BorderStyle="Solid"
  BorderWidth="1"
  CellPadding="3"
  GridLines="None"
  RowStyle-Font-Size="11pt"
  RowStyle-VerticalAlign="Top">
  
  <Fields>
  
  <asp:TemplateField 
    HeaderStyle-BackColor="#E0E0E0" 
    ItemStyle-BackColor="#E0E0E0">
    <ItemTemplate>
      <asp:Button CommandName="New" Text="New" Runat="Server"
        Font-Size="8pt" Width="45px"/>
      <asp:Button CommandName="Edit" Text="Edit" Runat="Server"
        Font-Size="8pt" Width="45px"/>
      <asp:Button CommandName="Delete" Text="Delete" Runat="Server"
        Font-Size="8pt" Width="45px"/>
    </ItemTemplate>
    <EditItemTemplate>
      <asp:Button CommandName="Update" Text="Update" Runat="Server"
        Font-Size="8pt" Width="45px"/>		
      <asp:Button CommandName="Cancel" Text="Cancel" Runat="Server"
        Font-Size="8pt" Width="45px"/>
    </EditItemTemplate>
    <InsertItemTemplate>
      <asp:Button CommandName="Insert" Text="Insert" Runat="Server"
        Font-Size="8pt" Width="45px"/>		
      <asp:Button CommandName="Cancel" Text="Cancel" Runat="Server"
        Font-Size="8pt" Width="45px"/>
    </InsertItemTemplate>
  </asp:TemplateField>
  
  <asp:BoundField	ReadOnly="True"
    DataField="BookID"
    HeaderText="ID: "
    HeaderStyle-BackColor="#E0E0E0"
    HeaderStyle-Font-Bold="True"/>
  
  <asp:TemplateField 
    HeaderText="Type: "
    HeaderStyle-BackColor="#E0E0E0"
    HeaderStyle-Font-Bold="True">
    <ItemTemplate>
      <asp:Label Text='<%# Eval("BookType") %>' Runat="Server"/>
    </ItemTemplate>
    <EditItemTemplate>
      <asp:DropDownList id="EditType" Runat="Server"
        DataSourceID="TypeSource"
        DataTextField="BookType"
        DataValueField="BookType" 
        SelectedValue='<%# Bind("BookType") %>'/>
    </EditItemTemplate>
  </asp:TemplateField>
  
  <asp:BoundField
    DataField="BookTitle"
    HeaderText="Title: "
    HeaderStyle-BackColor="#E0E0E0"	
    HeaderStyle-Font-Bold="True"/>
  
  <asp:BoundField	
    DataField="BookAuthor"
    HeaderText="Author: "
    HeaderStyle-BackColor="#E0E0E0"	
    HeaderStyle-Font-Bold="True"/>	
  	
  <asp:TemplateField 
    HeaderText="Description: "
    HeaderStyle-BackColor="#E0E0E0"
    HeaderStyle-Font-Bold="True">
    <ItemTemplate>
      <asp:Panel Width="400px" Height="110px" BorderWidth="1px" 
      BorderColor="#C0C0C0" ScrollBars="Auto" Runat="Server">
        <asp:Label Text='<%# Eval("BookDescription") %>' Font-Size="10pt" 
        Runat="Server"/>
      </asp:Panel>
    </ItemTemplate>
    <EditItemTemplate>
      <asp:TextBox id="EditDescription" Runat="Server"
        Text='<%# Bind("BookDescription") %>'
        TextMode="MultiLine" Height="110" Width="400px" 
        Font-Name="Arial" Font-Size="9pt"/>
    </EditItemTemplate>
  </asp:TemplateField>
  
  <asp:BoundField 
    DataField="BookPrice"
    HtmlEncode="False"
    DataFormatString="{0:C}"
    HeaderText="Price: "
    HeaderStyle-BackColor="#E0E0E0"	
    HeaderStyle-Font-Bold="True"/>
  
  <asp:BoundField 
    DataField="BookQty"
    HtmlEncode="False"
    DataFormatString="{0:D}"
    HeaderText="Qty: "
    HeaderStyle-BackColor="#E0E0E0"	
    HeaderStyle-Font-Bold="True"/>
  
  <asp:CheckBoxField 
    DataField="BookSale"
    HeaderText="Sale: "
    HeaderStyle-BackColor="#E0E0E0"
    HeaderStyle-Font-Bold="True"/>
  
  </Fields>

</asp:DetailsView>
Listing 9-21. Code for DetailsView with Bound and Template fields.

Default display of editing buttons is turned off by assigning "False" to the AutoGenerateInsertButton, AutoGenerateEditButton, and AutoGenerateDeleteButton properties. This same effect is achieved by not coding these properties. Also, event handlers are coded for the ItemInserting, ItemInserted, ItemUpdating, ItemUpdated, and ItemDeleted events. Subprograms are called on these events to validate entered data and to display process completion messages.

Default edit buttons are replaced by <asp:Button> controls coded in a TemplateField. This coding is repeated below.

<asp:TemplateField 
  HeaderStyle-BackColor="#E0E0E0" 
  ItemStyle-BackColor="#E0E0E0">
	
  <ItemTemplate>
    <asp:Button CommandName="New" Text="New" Runat="Server"
      Font-Size="8pt" Width="45px"/>
    <asp:Button CommandName="Edit" Text="Edit" Runat="Server"
      Font-Size="8pt" Width="45px"/>
    <asp:Button CommandName="Delete" Text="Delete" Runat="Server"
      Font-Size="8pt" Width="45px"/>
  </ItemTemplate>
	
  <EditItemTemplate>
    <asp:Button CommandName="Update" Text="Update" Runat="Server"
      Font-Size="8pt" Width="45px"/>		
    <asp:Button CommandName="Cancel" Text="Cancel" Runat="Server"
      Font-Size="8pt" Width="45px"/>
  </EditItemTemplate>
	
  <InsertItemTemplate>
    <asp:Button CommandName="Insert" Text="Insert" Runat="Server"
      Font-Size="8pt" Width="45px"/>		
    <asp:Button CommandName="Cancel" Text="Cancel" Runat="Server"
      Font-Size="8pt" Width="45px"/>
  </InsertItemTemplate>
	
</asp:TemplateField>
Listing 9-22. Code for DetailsView Template field with command buttons.

An <ItemTemplate> includes the "New," "Edit," and "Delete" buttons that initiate editing. An <EditItemTemplate> includes the "Update" and "Cancel" buttons common for display of update fields. An <InsertItemTemplate> includes controls for the "Insert" and "Cancel" buttons displayed on record additions. You need to made sure that the proper CommandName values are assigned to these buttons to work like the default text buttons.

The remainder of the DetailsView's display and editing fields are similar to those used previously in a GridView. BoundField, TemplateField, and other controls bind to database fields for updating existing records and adding new records to the database. Notice that none of the TemplateFields include <InsertItemTemplate> sections. This template can be defined along with an <EditItemTemplate> if the format of the insert field is different from that of an update field.

DetailsView Event Scripting

Scripts for the five events trapped for the DetailsView are shown below: ItemInserting, ItemInserted, ItemUpdating, ItemUpdated, and ItemDeleted.

<SCRIPT Runat="Server">

'-- OnItemInserting --
Sub Validate_Insert_Data (Src As Object, Args As DetailsViewInsertEventArgs)
  
  If Args.Values("BookID") = "" Then
    Args.Cancel = True
    EditMSG.Text = "-- Missing BookID. Record not added."
  End If
  
  If Not IsNumeric(Args.Values("BookPrice")) Then
    Args.Cancel = True
    EditMSG.Text = "-- Book Price is not numeric. Record not added."
  End If
  
  If Not IsNumeric(Args.Values("BookQty")) Then
    Args.Cancel = True
    EditMSG.Text = "-- Book Quantity is not numeric. Record not added"
  End If
  
  If Args.Cancel = False Then
    If Args.Values("BookPrice") < 0 _
    OR Args.Values("BookPrice") > 200 Then
      Args.Cancel = True
      EditMSG.Text = "-- Book Price out of range. Record not added"
    End If
  End If
  
  If Args.Cancel = False Then
    If Args.Values("BookQty") < 0 Then
      Args.Cancel = True
      EditMSG.Text = "-- Book Quantity out of range. Record not added"
    End If
  End If

End Sub

'-- OnItemInserted --
Sub Display_Insert_Msg (Src As Object, Args As DetailsViewInsertedEventArgs)
  EditMSG.Text = " Record " & Args.Values("BookID") & " added"
End Sub

'-- OnItemUpdating --
Sub Validate_Update_Data (Src As Object, Args As DetailsViewUpdateEventArgs)

  If Not IsNumeric(Args.NewValues("BookPrice")) Then
    Args.Cancel = True
    EditMSG.Text = "-- Book Price is not numeric. Record not updated."
  End If
  
  If Not IsNumeric(Args.NewValues("BookQty")) Then
    Args.Cancel = True
    EditMSG.Text = "-- Book Quantity is not numeric. Record not updated"
  End If
  
  If Args.Cancel = False Then
    If Args.NewValues("BookPrice") < 0 _
    OR Args.NewValues("BookPrice") > 200 Then
      Args.Cancel = True
      EditMSG.Text = "-- Book Price out of range. Record not updated"
    End If
  End If
  
  If Args.Cancel = False Then
    If Args.NewValues("BookQty") < 0 Then
      Args.Cancel = True
      EditMSG.Text = "-- Book Quantity out of range. Record not updated"
    End If
  End If

End Sub

'-- OnItemUpdated --
Sub Display_Update_Msg (Src As Object, Args As DetailsViewUpdatedEventArgs)
  EditMSG.Text = " Record " & Args.Keys("BookID") & " updated"
End Sub

'-- OnItemDeleted --
Sub Display_Delete_Msg (Src As Object, Args As DetailsViewDeletedEventArgs)
  EditMSG.Text = " Record " & Args.Keys("BookID") & " deleted"
End Sub

</SCRIPT>
Listing 9-23. Scripts for editing events of DetailsView.

When a new record's "Insert" button is clicked and an ItemInserting event is raised, the Validate_Insert_Data subprogram is called. A collection of Values properties is available for testing for an inserted record. The record must be supplied with an BookID value since this is the key for the record. Also, numeric fields must contain numeric data. If any field fails a validation test, inserting is cancelled. On an ItemInserted event, the Display_Insert_Msg subprogram is called and a record-added message is displayed.

Editing for the ItemUpdating event is similar except that no test is made for a valid BookID field since this field is not available for editing. On an ItemUpdated event, a record-updated message is displayed.

On an ItemDeleted event, a record-deleted message is displayed. There is no built-in confirmation step giving the user the option to cancel editing. This is a common precaution to take, and later examples implement this confirmation.