[referrenced]Master/Detail Editing - DetailsView

from:
http://msconline.maconstate.edu/tutorials/ASPNET2/ASPNET09/aspnet09-05.aspx

Record editing with a single DetailsView or FormView works fine for small database tables requiring few pages to navigate. For large recordsets, though, it may be difficult to locate particular records by paging through them sequentially. What is required is a table of contents to quickly locate records of interest, and a form for editing those that are found. These requirements are easily provided in a master/detail setup. In the following example, a GridView presents an index to all records in eCommerce.mdb database; a linked DetailsView gives editing access to individual records.

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

 
Number Name
BU1111 Microsoft Office Professional 2003
BU2222 WordPerfect Office 12
BU3333 Project 2003
DB1111 Access 2003
DB2222 SQL Server 2000 Standard
DB3333 FileMaker Pro 6
DP1111 FrameMaker 7.0
DP2222 QuarkXPress 6.0
GR1111 Photoshop CS
GR2222 Illustrator CS
1 2
Edit:
Number: BU1111
Type: Business Office
Name: Microsoft Office Professional 2003
Supplier: Microsoft
Description:
Microsoft Office Professional Edition 2003 can help you and your organization communicate information with immediacy and impact. New and familiar programs and improved functionality help you build powerful connections between people, information, and business processes.
Price: 419.99
Qty: 20
Sale:
Figure 9-24. Master/detail record editing.

Coding the GridView

Code for the master GridView and its AccessDataSource are shown below. A TemplateField containing <asp:LinkButton> controls both displays item numbers and configures them as command links for selecting products. The CommandName for the LinkButtons is "Select" to tie item numbers to the SelectCommand property of the AccessDataSource for the DetailsView.

<asp:AccessDataSource id="MasterSource" Runat="Server"
DataFile="../Databases/eCommerce.mdb"
SelectCommand="SELECT ItemNumber, ItemName FROM Products ORDER BY ItemNumber"/>
<asp:Label id="EditMSG" EnableViewState="False" ForeColor="Red" Runat="Server"/>
<asp:GridView id="GridView" DataSourceID="MasterSource" Runat="Server"
DataKeyNames="ItemNumber"
AutoGenerateColumns="False"
AllowPaging="True"
PageSize="10"
Width="250"
SelectedIndex="0"
SelectedRowStyle-BackColor="#E9E9E9"
HeaderStyle-BackColor="#E0E0E0"
HeaderStyle-Font-Bold="True"
Style="float:left">
<Columns>
<asp:TemplateField HeaderText="Number" HeaderStyle-Width="50">
<ItemTemplate>
<asp:LinkButton CommandName="Select" Runat="Server">
<%# Eval("ItemNumber") %>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Name" DataField="ItemName"/>
</Columns>
</asp:GridView>
Listing 9-37. Coding a master GridView.

Coding the DetailsView

The DetailsView employs an AccessDataSource whose SelectCommand is linked to the GridView selection through its SelectParameters. The GridView's SelectedValue becomes the @ItemNumber parameter for displaying the chosen record. A second AccessDataSource fills DropDownLists of item types during updating and inserting operations.

<asp:AccessDataSource id="DetailsSource" Runat="Server"
DataFile="../Databases/eCommerce.mdb"
SelectCommand="SELECT * FROM Products WHERE ItemNumber = @ItemNumber"
InsertCommand="INSERT INTO Products (ItemNumber, ItemType, ItemSupplier, ItemName, ItemDescription,
ItemPrice, ItemQuantity, ItemSale) VALUES (@ItemNumber, @ItemType, @ItemSupplier,
@ItemName, @ItemDescription,	@ItemPrice, @ItemQuantity, @ItemSale)"
UpdateCommand="UPDATE Products SET ItemType=@ItemType, ItemSupplier=@ItemSupplier,
ItemName=@ItemName, ItemDescription=@ItemDescription, ItemPrice=@ItemPrice,
ItemQuantity=@ItemQuantity, ItemSale=@ItemSale WHERE ItemNumber=@ItemNumber"
>
<SelectParameters>
<asp:ControlParameter ControlID="GridView" Name="ItemNumber" PropertyName="SelectedValue"/>
</SelectParameters>
</asp:AccessDataSource>
<asp:AccessDataSource id="TypeSource" Runat="Server"
DataFile="../Databases/eCommerce.mdb"
SelectCommand="SELECT DISTINCT ItemType FROM Products ORDER BY ItemType"/>
Listing 9-38. Linking a DetailsView to a master GridView via AccessDataSource parameters.

Code for the DetailsView is shown below. Editing buttons are supplied through a TemplateField containing Button controls configured as command buttons. Also, a set of delete confirmation buttons appears inside the DetailsView's ItemTemplate.

<asp:DetailsView id="DetailsView" DataSourceID="DetailsSource" Runat="Server"
AutoGenerateRows="False"
DataKeyNames="ItemNumber"
OnItemInserting="Validate_Insert_Data"
OnItemInserted="Display_Insert_Msg"
OnItemUpdating="Validate_Update_Data"
OnItemUpdated="Display_Update_Msg"
OnItemDeleting="Confirm_Delete"
OnItemCommand="Get_Command"
BorderStyle="Outset"
BorderWidth="1"
CellPadding="3"
GridLines="None">
<Fields>
<asp:TemplateField HeaderStyle-BackColor="#E0E0E0" HeaderStyle-Font-Bold="True"
HeaderStyle-HorizontalAlign="Right" ItemStyle-VerticalAlign="Top"
ItemStyle-BackColor="#E0E0E0" ItemStyle-ForeColor="#FF0000">
<HeaderTemplate>
Edit:
</HeaderTemplate>
<ItemTemplate>
<asp:Button CommandName="Edit" Text="Edit" Font-Size="8pt" Width="45" Runat="Server"/>
<asp:Button CommandName="New" Text="New" Font-Size="8pt" Width="45" Runat="Server"/>
<asp:Button CommandName="Delete" Text="Delete" Font-Size="8pt" Width="45" Runat="Server"/>
<asp:Label id="ConfirmDelete" Visible="False" EnableViewState="False" Runat="Server">
<asp:Label Text="Delete this record? " ForeColor="Red" EnableViewState="False" 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>
</ItemTemplate>
<EditItemTemplate>
<asp:Button CommandName="Update" Text="Update" Font-Size="8pt" Width="45" Runat="Server"/>
<asp:Button CommandName="Cancel" Text="Cancel" Font-Size="8pt" Width="45" Runat="Server"/>
</EditItemTemplate>
<InsertItemTemplate>
<asp:Button CommandName="Insert" Text="Insert" Font-Size="8pt" Width="45" Runat="Server"/>
<asp:Button CommandName="Cancel" Text="Cancel" Font-Size="8pt" Width="45" Runat="Server"/>
</InsertItemTemplate>
</asp:TemplateField>
<asp:BoundField	DataField="ItemNumber" ReadOnly="True" HeaderText="Number: "
HeaderStyle-BackColor="#E0E0E0"	HeaderStyle-Font-Bold="True"
ItemStyle-VerticalAlign="Top"/>
<asp:TemplateField HeaderText="Type: " HeaderStyle-BackColor="#E0E0E0"
HeaderStyle-Font-Bold="True" ItemStyle-VerticalAlign="Top">
<ItemTemplate>
<asp:Label Text='<%# Eval("ItemType") %>' Runat="Server"/>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList id="EditType" DataSourceID="TypeSource" Runat="Server"
DataTextField="ItemType" DataValueField="ItemType" SelectedValue='<%# Bind("ItemType") %>'/>
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField	DataField="ItemName" HeaderText="Name: "
HeaderStyle-BackColor="#E0E0E0"	HeaderStyle-Font-Bold="True"
ItemStyle-VerticalAlign="Top"/>
<asp:BoundField	DataField="ItemSupplier" HeaderText="Supplier: "
HeaderStyle-BackColor="#E0E0E0"	HeaderStyle-Font-Bold="True"
ItemStyle-VerticalAlign="Top"/>
<asp:TemplateField HeaderText="Description: " HeaderStyle-BackColor="#E0E0E0"
HeaderStyle-Font-Bold="True" ItemStyle-VerticalAlign="Top">
<ItemTemplate>
<asp:Panel Width="350px" Height="100px" BorderWidth="1px" BorderColor="#C0C0C0"
ScrollBars="Auto" Runat="Server">
<asp:Label Text='<%# Eval("ItemDescription") %>' Font-Size="10pt" Runat="Server"/>
</asp:Panel>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id="EditDescription" Text='<%# Bind("ItemDescription") %>' Runat="Server"
TextMode="MultiLine" Rows="5" Width="350px" Font-Name="Arial" Font-Size="9pt"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ItemPrice" HeaderText="Price: "
HeaderStyle-BackColor="#E0E0E0"	HeaderStyle-Font-Bold="True"
ItemStyle-VerticalAlign="Top" DataFormatString="{0:N}"/>
<asp:BoundField DataField="ItemQuantity" HeaderText="Qty: "
HeaderStyle-BackColor="#E0E0E0"	HeaderStyle-Font-Bold="True"
ItemStyle-VerticalAlign="Top" DataFormatString="{0:D}"/>
<asp:CheckBoxField DataField="ItemSale" HeaderText="Sale: "
HeaderStyle-BackColor="#E0E0E0"	HeaderStyle-Font-Bold="True"
ItemStyle-VerticalAlign="Top"/>
</Fields>
</asp:DetailsView>
Listing 9-39. Code for DetailsView to display records selected from GridView.

DetailsView Scripting

Scripting for the DetailsView uses similar techniques as before. Click events are trapped by OnItemInserting, OnItemInserted, OnItemUpdating, OnItemUpdated, OnItemDeleting, and OnItemCommand handlers. During inserting and updating, subprograms validate entered data; during deletion, confirmation buttons are presented. All subprograms display appropriate messages about editing status.

Sub Validate_Insert_Data (Src As Object, Args As DetailsViewInsertEventArgs)
If Args.Values("ItemNumber") = "" Then
Args.Cancel = True
EditMSG.Text = "-- Missing item number"
End If
If Args.Values("ItemName") = "" Then
Args.Cancel = True
EditMSG.Text = "-- Missing item name"
End If
If Args.Values("ItemSupplier") = "" Then
Args.Cancel = True
EditMSG.Text = "-- Missing item supplier"
End If
If Args.Values("ItemDescription") = "" Then
Args.Cancel = True
EditMSG.Text = "-- Missing item description"
End If
If Not IsNumeric(Args.Values("ItemPrice")) Then
Args.Cancel = True
EditMSG.Text = "-- Item price is not numeric"
Else
If Args.Values("ItemPrice") < 0 Then
Args.Cancel = True
EditMSG.Text = "-- Item price is out of range"
End If
End If
If Not IsNumeric(Args.Values("ItemQuantity")) Then
Args.Cancel = True
EditMSG.Text = "-- Item quantity is not numeric"
Else
If Args.Values("ItemQuantity") < 0 Then
Args.Cancel = True
EditMSG.Text = "-- Item quantity is out of range"
End If
End If
End Sub
Sub Display_Insert_Msg (Src As Object, Args As DetailsViewInsertedEventArgs)
EditMSG.Text = "-- Record " & Args.Values("ItemNumber") & " added"
GridView.DataBind()
End Sub
Sub Validate_Update_Data (Src As Object, Args As DetailsViewUpdateEventArgs)
If Args.NewValues("ItemName") = "" Then
Args.Cancel = True
EditMSG.Text = "-- Missing item name"
End If
If Args.NewValues("ItemSupplier") = "" Then
Args.Cancel = True
EditMSG.Text = "-- Missing item supplier"
End If
If Args.NewValues("ItemDescription") = "" Then
Args.Cancel = True
EditMSG.Text = "-- Missing item description"
End If
If Not IsNumeric(Args.NewValues("ItemPrice")) Then
Args.Cancel = True
EditMSG.Text = "-- Item price is not numeric"
Else
If Args.NewValues("ItemPrice") < 0 Then
Args.Cancel = True
EditMSG.Text = "-- Item price is out of range"
End If
End If
If Not IsNumeric(Args.NewValues("ItemQuantity")) Then
Args.Cancel = True
EditMSG.Text = "-- Item quantity is not numeric"
Else
If Args.NewValues("ItemQuantity") < 0 Then
Args.Cancel = True
EditMSG.Text = "-- Item quantity is out of range"
End If
End If
End Sub
Sub Display_Update_Msg (Src As Object, Args As DetailsViewUpdatedEventArgs)
EditMSG.Text = "-- Record " & Args.Keys("ItemNumber") & " updated"
End Sub
Sub Confirm_Delete (Src As Object, Args As DetailsViewDeleteEventArgs)
Args.Cancel = True
Dim ConfirmLabel As Label = DetailsView.Rows(0).FindControl("ConfirmDelete")
ConfirmLabel.Visible = True
ViewState("ItemNumber") = Args.Keys("ItemNumber")
End Sub
Sub Get_Command (Src As Object, Args As DetailsViewCommandEventArgs)
If Args.CommandName = "Yes" Then
DetailsSource1.DeleteCommand = "DELETE FROM Products WHERE ItemNumber = '" & ViewState("ItemNumber") & "'"
DetailsSource1.Delete()
GridView.DataBind()
EditMSG.Text = " Record " & ViewState("ItemNumber") & " deleted"
End If
End Sub
Listing 9-40. Script to validate and update records through master/detail GridView/DetailsView.

You will notice a slight difference in coding from previous scripts to locate the ConfirmLabel containing "Yes" and "No" delete confirmation buttons. In coding this technique for a previous FormView, the control's FindControl("id") method is used. For a DetailsView, however, this method's format is different as shown below.

Sub Confirm_Delete (Src As Object, Args As DetailsViewDeleteEventArgs)
Args.Cancel = True
Dim ConfirmLabel As Label = DetailsView.Rows(0).FindControl("ConfirmDelete")
ConfirmLabel.Visible = True
ViewState("ItemNumber") = Args.Keys("ItemNumber")
End Sub
Listing 9-41. Finding controls in the first row of a DetailsView.

Whereas a FormView contains a single Row object that is searched for a control, a DetailsView contains multiple Rows, one for each visible row of the control. These rows are indexed beginning with 0, and this index is used to point to the particular row to search to find an enclosed control. In the current DetailsView, the confirmation buttons and their container Label appear in the first row (index = 0). This row index points the FindControl() method to the appropriate row to search for the ConfirmLabel, which is then made visible.

Incidentally, to locate a control on other rows of the DetailsView, or of a GridView, the row index is not known in advance or cannot be anticipated. However, arguments passed to subprograms when events occur on a row include the RowIndex property for that row. This property value then points to the row of interest. For example, to locate a Label with id="MSGLabel" on the same row as an "Update" button that is clicked, the following code can be used.

Sub Find_Label (Src As Object, Args As DetailsViewUpdateEventArgs)
Dim FoundLabel As Label = MyDetailsView.Rows(Args.RowIndex).FindControl("MSGLabel")
End Sub

<asp:DetailsView id="MyDetailsView" ...
OnRowUpdating="Find_Label"
...
Listing 9-42. Finding controls in a clicked row of a DetailsView.

Notice in the example GridView that when a new record is added or an existing record is deleted that the GridView is bound again from its AccessDataSource: GridView.DataBind(). This re-binding ensures that the GridView correctly represents the changed contents of the Products table after records are added and deleted.

A FormView can be easily substituted for the above DetailsView. The one from the previous FormView editing tutorial can be used by linking it to the GridView. Slight script changes are needed for subprogram arguments and for locating embedded controls. Still, it is nearly a matter of swapping one control for another.

posted @ 2008-01-20 01:10  N/A2011  阅读(624)  评论(0编辑  收藏  举报