Editing Records - FormView

A FormView control can include editing features to add new records to a database, update existing records, and delete existing records. These functions can be performed without scripting, or scripts can be added for pre- or post-processing activities. In the following example, a FormView includes "Edit," "New," and "Delete" buttons for editing books from the BooksDB.mdb 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

 
Edit New Delete
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-19. Editing with a FormView.

Coding the FormView

Code for the FormView and its AccessDataSources for the above example is shown below. This code may appear more extensive than for a DetailsView with the same functionality. However, much of the code pertains to formatting the forms inside XHTML tables. There still remain an ItemTemplate, EditItemTemplate, and InsertItemTemplate as comparable templates for arranging display and edit fields.

The FormView uses an AccessDataSource that includes three SQL statements. The SelectCommand, InsertCommand, and UpdateCommand statements are identical to those used previously to edit a selected record in a DetailsView. You might notice a missing DeleteCommand. In this example, record deletion is scripted rather than taking place automatically through the AccessDataSource. This deletion process is described below. A second AccessDataSource supplies values for DropDownLists of book types during updates and additions.

A embedded Cascading Style Sheet is included in the code. Use of the style sheet makes it easier to consistently style the three separate tables in the ItemTemplate, EditItemTemplate, and InsertItemTemplate.

<style type="text/css">
  table#ItemTable th {font-size:11pt; text-align:left; vertical-align:top; 
                      background-color:#E0E0E0}
  table#ItemTable td {font-size:11pt; vertical-align:top}
  table#EditTable th {font-size:11pt; text-align:left; vertical-align:top; 
                      background-color:#E0E0E0}
  table#EditTable td {font-size:11pt; vertical-align:top}
  table#AddTable th  {font-size:11pt; text-align:left; vertical-align:top; 
                      background-color:#E0E0E0}
  table#AddTable td  {font-size:11pt; vertical-align:top}
  .buttons           {background-color:#E0E0E0}
</style>

<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"
/>

<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="&nbsp;" ForeColor="Red" Runat="Server"
EnableViewState="False"/>

<asp:Panel id="ConfirmDelete" Visible="False" EnableViewState="False" 
Runat="Server">
  <asp:Label Text="Delete this record? " ForeColor="Red" Runat="Server"/>
  <asp:Button Text="Yes" OnClick="Delete_Record" Runat="Server"
    Font-Size="7pt" Height="17px" Width="30px"/>
  <asp:Button Text="No" OnClick="Cancel_Delete" Runat="Server"
    Font-Size="7pt" Height="17px" Width="30px"/>
</asp:Panel>

<asp:FormView id="FormView" DataSourceID="BookSource"  Runat="Server"
  DataKeyNames="BookID"
  OnItemInserting="Validate_Insert_Data"
  OnItemInserted="Display_Insert_Msg"
  OnItemUpdating="Validate_Update_Data"
  OnItemUpdated="Display_Update_Msg"
  OnItemDeleting="Confirm_Delete"
  AllowPaging="True"
  GridLines="Both">
  
  <ItemTemplate>
  <table id="ItemTable" border="0" cellpadding="3" cellspacing="0">
  <tr>
    <th></th>
    <td class="buttons">
      <asp:LinkButton CommandName="Edit" Text="Edit" Runat="Server"/>
      <asp:LinkButton CommandName="New" Text="New" Runat="Server"/>
      <asp:LinkButton CommandName="Delete" Text="Delete" Runat="Server"/>
    </td>
  </tr>
  <tr>
    <th>ID</th>
    <td><asp:Label Text='<%# Eval("BookID") %>' Runat="Server"/></td>
  </tr>
  <tr>
    <th>Type</th>
    <td><asp:Label Text='<%# Eval("BookType") %>' Runat="Server"/></td>
  </tr>
  <tr>
    <th>Title</th>
    <td><asp:Label Text='<%# Eval("BookTitle") %>' Runat="Server"/></td>
  </tr>
  <tr>
    <th>Author</th>
    <td><asp:Label Text='<%# Eval("BookAuthor") %>' Runat="Server"/></td>
  </tr>
  <tr>
    <th>Description</th>
    <td><asp:Panel Width="350px" Height="95px" BorderWidth="1px" 
        BorderColor="#C0C0C0" ScrollBars="Auto" Runat="Server">
          <asp:Label Text='<%# Eval("BookDescription") %>' Font-Size="10pt" 
          Runat="Server"/>
        </asp:Panel></td>
  </tr>
  <tr>
    <th>Price</th>
    <td><asp:Label Text='<%# String.Format("{0:C}", Eval("BookPrice")) %>' 
        Runat="Server"/></td>
  </tr>
  <tr>
    <th>Qty</th>
    <td><asp:Label Text='<%# String.Format("{0:D}", Eval("BookQty")) %>'
        Runat="Server"/></td>
  </tr>
  <tr>
    <th>Sale</th>
    <td><asp:CheckBox Checked='<%# Eval("BookSale") %>' Enabled="False"
        Runat="Server"/></td>
  </tr>
  </table>
  </ItemTemplate>
  
  <EditItemTemplate>
  <table id="EditTable" border="0" cellpadding="3" cellspacing="0">
  <tr>
    <th></th>
    <td class="buttons">
      <asp:LinkButton CommandName="Update" Text="Update" Runat="Server"/>
      <asp:LinkButton CommandName="Cancel" Text="Cancel" Runat="Server"/>
    </td>
  </tr>
  <tr>
    <th>ID</th>
    <td><asp:Label Text='<%# Eval("BookID") %>' Runat="Server"/></td>
  </tr>
  <tr>
    <th>Type</th>
    <td><asp:DropDownList id="BookType" Runat="Server"
        DataSourceID="TypeSource"
        DataTextField="BookType"
        DataValueField="BookType"
        SelectedValue='<%# Bind("BookType") %>'/></td>
  </tr>
  <tr>
    <th>Title</th>
    <td><asp:TextBox id="EditTitle" Runat="Server"
        Text='<%# Bind("BookTitle") %>'/></td>
  </tr>
  <tr>
    <th>Author</th>
    <td><asp:TextBox id="EditAuthor" Runat="Server"
        Text='<%# Bind("BookAuthor") %>'/></td>
  </tr>
  <tr>
    <th>Description</th>
    <td><asp:TextBox id="EditDescription" Runat="Server
        Text='<%# Bind("BookDescription") %>'"
        TextMode="MultiLine" Height="95" Width="350px"
        Font-Name="Arial" Font-Size="9pt"/></td>
  </tr>
  <tr>
    <th>Price</th>
    <td><asp:TextBox id="EditPrice" Runat="Server"
        Text='<%# Bind("BookPrice") %>'
        Width="50px"/></td>
  </tr>
  <tr>
    <th>Quantity</th>
    <td><asp:TextBox id="EditQty" Runat="Server"
        Text='<%# Bind("BookQty") %>'
        Width="50px"/></td>
  </tr>
  <tr>
    <th>Sale</th>
    <td><asp:CheckBox id="EditSale" Runat="Server"
        Checked='<%# Bind("BookSale") %>'/></td>
  </tr>
  </table>
  </EditItemTemplate>
  
  <InsertItemTemplate>
  <table id="AddTable" border="0" cellpadding="3" cellspacing="0">
  <tr>
    <th></th>
    <td class="buttons">
      <asp:LinkButton CommandName="Insert" Text="Insert" Runat="Server"/>
      <asp:LinkButton CommandName="Cancel" Text="Cancel" Runat="Server"/>
    </td>
  </tr>
  <tr>
    <th>ID</th>
    <td><asp:TextBox id="AddBookID" Runat="Server"
        Text='<%# Bind("BookID") %>'/></td>
  </tr>
  <tr>
    <th>Type</th>
    <td><asp:DropDownList id="AddType" Runat="Server"
        DataSourceID="TypeSource"
        DataTextField="BookType"
        DataValueField="BookType"
        SelectedValue='<%# Bind("BookType") %>'/></td>
  </tr>
  <tr>
    <th>Title</th>
    <td><asp:TextBox id="AddTitle" Runat="Server"
        Text='<%# Bind("BookTitle") %>'/></td>
  </tr>
  <tr>
    <th>Author</th>
    <td><asp:TextBox id="AddAuthor" Runat="Server"
        Text='<%# Bind("BookAuthor") %>'/></td>
  </tr>
  <tr>
    <th>Description</th>
    <td><asp:TextBox id="AddDescription" Runat="Server"
        Text='<%# Bind("BookDescription") %>'
        TextMode="MultiLine" Rows="5" Width="350px"
        Font-Name="Arial" Font-Size="9pt"/></td>
  </tr>
  <tr>
    <th>Price</th>
    <td><asp:TextBox id="AddPrice" Runat="Server"
        Text='<%# Bind("BookPrice") %>'/></td>
  </tr>
  <tr>
    <th>Qty</th>
    <td><asp:TextBox id="AddQty" Runat="Server"
        Text='<%# Bind("BookQty") %>'/></td>
  </tr>
  <tr>
    <th>Sale</th>
    <td><asp:CheckBox id="AddSale" Runat="Server"
        Checked='<%# Bind("BookSale") %>'/></td>
  </tr>
  </table>
  </InsertItemTemplate>

</asp:FormView>
Listing 9-24. Code for FormView with editing.

The FormView requires three templates, one for viewing a record (ItemTemplate), one for updates (EditItemTemplate), and one for additions (InsertItemTemplate). All three templates include <table> tags to arrange labels and controls for formatted display. All templates must include buttons to trigger editing activity. LinkButtons are used in this example. These buttons must include proper CommandNames for editing (Edit, New, and Delete), for updating (Update and Cancel), and for inserting (Insert and Cancel). Data display controls for updating and inserting records must use editable controls along with Bind() expressions so that changed or inserted values can be posted back to the database.

Like the GridView and DetailsView, a FormView immediately deletes a record when the "Delete" button is clicked. For this example, a confirmation step is added. When the button is clicked, a pair of "Yes" and "No" buttons appear to confirm or cancel deletion. These buttons are coded inside a Panel control that is initially hidden.

<asp:Panel id="ConfirmDelete" Visible="False" EnableViewState="False" 
Runat="Server">
  <asp:Label Text="Delete this record? " ForeColor="Red" Runat="Server"/>
  <asp:Button Text="Yes" OnClick="Delete_Record" Runat="Server"
    Font-Size="7pt" Height="17px" Width="30px"/>
  <asp:Button Text="No" OnClick="Cancel_Delete" Runat="Server"
    Font-Size="7pt" Height="17px" Width="30px"/>
</asp:Panel>
Listing 9-25. Code for delete confirmation display for FormView.

This Panel is not part of the FormView. It appears outside and immediately preceding the FormView. It is made visible by a Confirm_Delete subprogram that is called on the ItemDeleting event that occurs when the "Delete" button is clicked. This subprogram is described below.

FormView Events and Event Handlers

"Insert," "Update," and "Delete" buttons for the FormView have events associated with them for calling subprograms to intercept these processes. These events, their event handlers, and arguments of called subprograms are listed below. Except for argument names, these events and handlers are the same as those associated with a DetailsView.

Event Event Handler Signature Description
ItemInserting OnItemInserting FormViewInsertEventArgs A new record is being added to the data source but has not yet been written.
ItemInserted OnItemInserted FormViewInsertedEventArgs A new record has been written to the data source.
ItemUpdating OnItemUpdating FormViewUpdateEventArgs A record is being updated but has not yet been rewritten to the data source.
ItemUpdated OnItemUpdated FormViewUpdatedEventArgs An updated record has been rewritten to the data source.
ItemDeleting OnItemDeleting FormViewDeleteEventArgs A record is being deleted from the data source but has not yet been deleted.
ItemDeleted OnItemDeleted FormViewDeletedEventArgs A record has been deleted from the data source.
Figure 9-20. FormView event handlers and subprogram argument signatures.

As in the case with the DetailsView, subprograms called by these event handlers expose event properties that can be investigated. These properties are listed below and are identical to those exposed through DetailsView events.

--FormViewInsertEventArgs Properties--

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

--FormViewInsertedEventArgs Properties--

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

--FormViewUpdateEventArgs Properties--

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

--FormViewUpdatedEventArgs Properties--

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

--FormViewDeleteEventArgs Properties--

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

--FormViewDeletedEventArgs Properties--

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

FormView Event Scripting

Scripts for the OnInserting, OnInserted, OnUpdating, OnUpdated, and OnDeleting events trapped for the example FormView are shown below. Except for added functionality for the OnDeleting event, the remaining subprograms are identical to those used with the previous DetailsView.

<SCRIPT Runat="Server">

'-- OnItemInserting --
Sub Validate_Insert_Data (Src As Object, Args As FormViewInsertEventArgs)

  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 FormViewInsertedEventArgs)
  EditMSG.Text = " Record " & Args.Values("BookID") & " added"
End Sub

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

  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 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 _
    OR Args.NewValues("BookPrice") > 200 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 FormViewUpdatedEventArgs)
  EditMSG.Text = " Record " & Args.Keys("BookID") & " updated"
End Sub

'-- OnItemDeleting --
Sub Confirm_Delete (Src As Object, Args As FormViewDeleteEventArgs)
  
  Args.Cancel = True
  ConfirmDelete.Visible = True
  EditMSG.Visible = False
  ViewState("BookID") = Args.Keys("BookID")
  
End Sub

Sub Delete_Record (Src As Object, Args As EventArgs)
  
  BookSource.DeleteCommand = "DELETE FROM Books " & _
                             "WHERE BookID = '" & ViewState("BookID") & "'"
  BookSource.Delete()
  EditMSG.Text = " Record " & ViewState("BookID") & " deleted"
  
End Sub

Sub Cancel_Delete (Src As Object, Args As EventArgs)
  
  ConfirmDelete.Visible = False

End Sub

</SCRIPT>
Listing 9-26. Scripts for editing events of FormView.

When a new record's "Insert" button is clicked and an ItemInserting event is raised, the Validate_Insert_Data subprogram is called. The record must be supplied with a 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.

Delete Confirmation

When the "Delete" button is clicked and an ItemDeleting event occurs, the Confirm_Delete subprogram is called to immediately cancel the delete event and to make the ConfirmDelete Panel visible with its confirmation buttons. Since the delete event is cancelled, the Args.Keys("BookID") reference to the BookID key for this record is lost to subsequent subprograms to delete the record should it be confirmed. Therefore, this key is saved to a View State variable, ViewState("BookID"), for subsequent retrieval.

Sub Confirm_Delete (Src As Object, Args As FormViewDeleteEventArgs)

  Args.Cancel = True
  ConfirmDelete.Visible = True
  EditMSG.Visible = False
  ViewState("BookID") = Args.Keys("BookID")

End Sub
Listing 9-27. Code to activate delete confirmation Panel of FormView.

This is the case if the "Yes" button is clicked and the Delete_Record subprogram is called. This subprogram composes a DELETE statement, using the saved ViewState("BookID") to identify the key of the record to be deleted. The statement is assigned to the DeleteCommand property of AccessDataSource for the FormView, and its Delete() method is called to delete the record. This scripted delete operation is the reason a DeleteCommand statement is not needed in the AccessDataSource.

Sub Delete_Record (Src As Object, Args As EventArgs)

  BookSource.DeleteCommand = "DELETE FROM Books " & _
                             "WHERE BookID = '" & ViewState("BookID") & "'"
  BookSource.Delete()
  EditMSG.Text = " Record " & ViewState("BookID") & " deleted"

End Sub
Listing 9-28. Script to delete a FormView record.

If, on the other hand, the "No" confirmation button is clicked, no action is taken on the record. Instead, the Cancel_Delete subprogram is called simply to hide the confirmation Panel.

Sub Cancel_Delete (Src As Object, Args As EventArgs)

  ConfirmDelete.Visible = False

End Sub
Listing 9-29. Script to cancel deletion of a FormView record.

This method of coding the FormView with its AccessDataSources and scripts can be applied to a DetailsView or GridView to supply record-deletion confirmation in these controls.

Using Command Events

In the above FormView the delete confirmation buttons appear outside the FormView itself. As a visual option you may wish to incorporate the "Yes" and "No" buttons inside the control as you can see by clicking the "Delete" button in the following FormView.

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-22. Editing with a FormView.

Coding for the FormView is similar to the previous example. One difference is that the LinkButton controls are coded here as Button controls. A second difference is in the section of the ItemTemplate where confirmation buttons are included along with the "Edit," "New," and "Delete" buttons. In the previous example, these "Yes" and "No" buttons are enclosed inside a Panel to control their visibility. Here they are enclosed inside a Label control. A Label is used so the confirmation buttons appear on the same line as the edit buttons (a Panel control causes a line break). As before, the buttons are initially hidden since the ConfirmDelete Label that contains them is hidden.

<asp:FormView id="FormView" DataSourceID="BookSource"  Runat="Server"
  ...
  OnItemDeleting="Confirm_Delete"
  OnItemCommand="Get_Command"
 >

  <ItemTemplate>
  <table id="ItemTable" border="0" cellpadding="3" cellspacing="0">
  <tr>
    <th></th>
    <td class="buttons">
      <asp:Button CommandName="Edit" Text="Edit" Font-Size="9pt" Width="50"
        Runat="Server"/>
      <asp:Button CommandName="New" Text="New" Font-Size="9pt" Width="50"
        Runat="Server"/>
      <asp:Button CommandName="Delete" Text="Delete" Font-Size="9pt"
        Width="50" Runat="Server"/>&nbsp;
      
      <asp:Label id="ConfirmDelete" Visible="False" EnableViewState="False"
      Runat="Server">
        <asp:Label Text="Delete this record? " ForeColor="Red" 
          Runat="Server"/>
        <asp:Button Text="Yes" CommandName="Yes" Font-Size="8pt" Width="30px"
          Runat="Server"/>
        <asp:Button Text="No" CommandName="No" Font-Size="8pt" Width="30px"
          Runat="Server"/>
      </asp:Label>
    
    </td>
  </tr>
  ...
  
  <EditItemTemplate>
  <table id="EditTable" border="0" cellpadding="3" cellspacing="0">
  <tr>
    <th></th>
    <td class="buttons">
      <asp:Button CommandName="Update" Text="Update" Font-Size="9pt" 
        Width="50" Runat="Server"/>
      <asp:Button CommandName="Cancel" Text="Cancel" Font-Size="9pt" 
        Width="50" Runat="Server"/>
    </td>
  </tr>
  <tr>
  ...
  
  <InsertItemTemplate>
  <table id="AddTable" border="0" cellpadding="3" cellspacing="0">
  <tr>
    <th></th>
    <td class="buttons">
      <asp:Button CommandName="Insert" Text="Insert" Font-Size="9pt" 
        Width="50" Runat="Server"/>
      <asp:Button CommandName="Cancel" Text="Cancel" Font-Size="9pt" 
        Width="50" Runat="Server"/>
    </td>
  </tr>
  ...

</asp:FormView>
Listing 9-30. Coding a FormView with command buttons.

Because the confirmation buttons are now inside, and part of, the FormView, they are given CommandName properties ("Yes" and "No") just like other buttons in a FormView. Also, the FormView is given an OnItemCommand event handler to respond to these command buttons by calling the Get_Command subprogram.

These command names replace the subprogram calls of the previous example. Subprograms Confirm_Delete, Delete_Record, and Cancel_Delete are no longer required, replaced by two new subprograms described below.

The other event handlers for the FormView—OnItemInserting, OnItemInserted, OnItemUpdating, OnItemUpdated, and OnItemDeleting—are associated with the special command names New, Insert, Edit, Update, and Delete. The Command names Yes and No, however, do not have special event handlers. Any buttons with undefined command names are handled by the general-purpose OnItemCommand event handler. In this example, the undefined command names "Yes" and "No" call the Get_Command subprogram through this handler. If preferred, any or all of the special event handlers can be replaced by the OnItemCommand hander to sort out any and all of the command names appearing in a FormView.

When the "Delete" button is clicked, the OnItemDeleting event handler calls the Confirm_Delete subprogram just as in the previous example. This subprogram is coded differently, however, since its purpose now is to make visible the confirmation buttons inside the FormView. A different method is required from the previous example of directly setting the Visible property of the ConfirmDelete Panel that resides outside the FormView.

Sub Confirm_Delete (Src As Object, Args As FormViewDeleteEventArgs)

  Args.Cancel = True
  Dim ConfirmLabel As Label = FormView.FindControl("ConfirmDelete")
  ConfirmLabel.Visible = True
  ViewState("BookID") = Args.Keys("BookID")

End Sub
Listing 9-31. Finding a FormView control.

First, the confirmation Label must be "found" in the FormView. The FormView's FindControl() method locates a control by its id value, after which it is assigned to a variable of the same type (a Label type in this instance). Once this control has been found and assigned to a variable, its Visible property is set to True, thereby revealing the "Yes" and "No" confirmation buttons. As before, the key of the currently displayed record is saved to ViewState("BookID") for deletion of this record, if requested, in a different subprogram.

When either of the two confirmation buttons is clicked, an ItemCommand event is raised and the Get_Command subprogram is called by the FormView's OnItemCommand event handler. This subprogram has the argument FormViewCommandEventArgs and is shown below.

Sub Get_Command (Src As Object, Args As FormViewCommandEventArgs)

  If Args.CommandName = "Yes" Then
    BookSource.DeleteCommand = "DELETE FROM Books" & _
                               "WHERE BookID = '" & ViewState("BookID") & "'"
    BookSource.Delete()
    EditMSG.Text = " Record " & ViewState("BookID") & " deleted"
  End If

End Sub
Listing 9-32. Trapping a FormView command event.

Action needs to be taken only on a click of the "Yes" button to delete the associated record. Therefore, if the command name passed to the subprogram (Args.CommandName) is "Yes," then an SQL DELETE statement is issued through the FormView's AccessDataSource. The record identified in ViewState("BookID") is deleted. If the "No" button is clicked (which calls this same subprogram), no action is taken. In either case, the confirmation buttons are hidden since their container Label is coded with EnableViewState="False" to revert to hidden status any time a page post-back occurs.