Master/Detail Editing - FormView
When using a DetailsView along with a GridView for master/detail editing, you are limited
to display of record details in a vertical column of individual fields. Although there is
nothing particularly wrong with this alignment, it reduces somewhat the flexibility you have
in arranging fields for display. With a FormView and its templates, however, a single cell
(a single Row object) gives you more choices on how to arrange headings
and fields within this display area.
In the following example, a GridView handles record updating and deleting for the
BooksDB.mdb database. Since a GridView does not supply record inserting
functionality, a FormView sitting atop the GridView takes on this function. Fields are arranged
horizontally along a row to match the display format of the GridView. This is not a true
master/detail arrangement since the FormView and GridView are not linked. They operate as
two distinct controls. However, their appearance is suggestive of a master/detail application.
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
|
|
DB111
|
Database
|
Oracle Database
|
K. Loney
|
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.
|
$69.99
|
10
|
|
|
|
DB222
|
Database
|
Databases in Depth
|
C. J. Date
|
In Database in Depth, author and well-known database authority Chris Date lays out the fundamentals of the relational model. Don't let a lack to formal education in database theory hold you back. Instead, let Chris's clear explanation of relational concepts, set theory, the difference between model and implementation, relational algebra, normalization, and much more set you apart and well above the competition when it comes to getting work done with a relational database.
|
$29.95
|
6
|
|
|
|
DB333
|
Database
|
Database Processing
|
D. Kroenke
|
Revised to reflect the needs of today's users, this 10th edition of Database Processing assures that you will learn marketable skills. By presenting SQL SELECT statements near the beginning of the book readers will know early on how to query data and obtain results-seeing firsthand some of the ways that database technology is useful in the marketplace. By utilizing free software downloads, you will be able to actively use a DBMS product by the end of the 2nd chapter. Each topic appears in the context of accomplishing practical tasks. Its spiral approach to database design provides users with enhanced information not available in other database books on the market.
|
$136.65
|
12
|
|
|
|
DB444
|
Database
|
Access Database Design
|
S. Roman
|
When using software products with graphical interfaces, we frequently focus so much on the details of how to use the interface that we forget about the general concepts that allow us to understand and use the software effectively. This is particularly true of a powerful database product like Microsoft Access. Novice, and sometimes even experienced, programmers are so concerned with how something is done in Access that they often lose sight of the general principles that underlie their database applications. Access Database Design and Programming takes you behind the details of the Access interface, focusing on the general knowledge necessary for Access power users or developers to create effective database applications.
|
$34.95
|
25
|
|
|
|
DB555
|
Database
|
SQL Server 2005
|
P. Debetta
|
Get a developer-focused introduction to the new programmability features in the next version of Microsoft SQL Server-including integration with the Microsoft .NET Framework-and learn powerful new ways to manipulate your servers. Whether you're a developer currently working with T-SQL or Microsoft Visual Studio.NET, or you're responsible for database administration, you'll see how to draw from your existing skills and knowledge to exploit new SQL Server technology. With introductory-level code samples written in both T-SQL and C#, you'll understand how to take advantage of the cross-platform interoperability, native support for XML and Web services, shared language base, and other programming innovations to build better solutions from business intelligence to enterprise data management.
|
$29.99
|
0
|
|
|
Figure 9-25. Master/detail editing with a FormView and GridView.
Coding the FormView
Two AccessDataSource controls are needed for the FormView. One is for inserting new records
into the database, the second is to supply book types for the DropDownList of choices. Although
the FormView does not display selected records (it is used only to add new records), it
still requires a SelectCommand with a record selection to make the
FormView visible. If its binding is null, the form does not display. Therefore, an arbitrary
selection is made of the first record in the Books table
(SELECT TOP 1 * FROM Books). This record is never displayed
because the FormView's ItemTemplate does not include binding fields. However, it ensures that
the FormView is always visible.
<asp:AccessDataSource id="AddSource" Runat="Server"
DataFile="../Databases/BooksDB.mdb"
SelectCommand="SELECT TOP 1 * FROM Books"
InsertCommand="INSERT INTO Books (BookID, BookType, BookTitle, BookAuthor,
BookDescription, BookPrice, BookQty, BookSale)
VALUES (@BookID, @BookType, @BookTitle, @BookAuthor,
@BookDescription, @BookPrice, @BookQty, @BookSale)"
/>
<asp:AccessDataSource id="TypeSource" Runat="Server"
DataFile="../Databases/BooksDB.mdb"
SelectCommand="SELECT DISTINCT BookType FROM Books ORDER BY BookType"
/>
Listing 9-43. AccessDataSources for FormView used with a master GridView.
Coding for the FormView is shown below along with the message display and delete confirmation
areas. Notice that exacting measurements are used to position the FormView precisely in
alignment with the GridView so that it visually appears almost as part of the GridView.
Also notice that the record confirmation area is positioned outside the FormView and
the GridView to which it applies. In this location it is not necessary to search for it with the
FindControl() method. It is directly accessible on the page. Also, the
"Yes" and "No" buttons can directly call subprograms rather than being configured as GridView
command buttons. A CSS style sheet is provided for the XHTML tables used in the FormView's
templates.
Since the FormView is used only for record additions, it requires only those event handlers
related to ItemInserting and ItemInserted events. The former calls a subprogram to validate
entered data, the latter to rebind the DataGrid to reflect additions.
<h3>Book Edit</h3>
<asp:Label id="EditMSG" Height="25" ForeColor="Red" Runat="Server"
EnableViewState="False"/>
<asp:Label id="ConfirmDelete" Visible="False" Runat="Server"
EnableViewState="False" Height="25">
<asp:Label Text="Delete this record? " Runat="Server"
ForeColor="Red" EnableViewState="False"/>
<asp:Button Text="Yes" OnClick="Delete_Record" Runat="Server"
Font-Size="7pt" Width="30px"/>
<asp:Button Text="No" OnClick="Cancel_Delete" Runat="Server"
Font-Size="7pt" Width="30px"/>
</asp:Label>
<style type="text/css">
table#Head {border-collapse:collapse}
table#Head th {font-size:11pt; background-color:#E0E0E0}
table#Head td {font-size:11pt}
table#Edit {width:630px; border-collapse:collapse}
table#Insert {border-collapse:collapse}
table#Insert td {font-size:10pt}
</style>
<asp:FormView id="AddForm" DataSourceID="AddSource" Runat="Server"
InsertRowStyle-BackColor="#00EE00"
OnItemInserting="Validate_Insert_Data"
OnItemInserted="Insert_Record">
<HeaderTemplate>
<table id="Head" border="1">
<tr>
<th><asp:Label Text="Edit" Width="70px" Runat="Server"/></th>
<th><asp:Label Text="ID" Width="45px" Runat="Server"/></th>
<th><asp:Label Text="Type" Width="80px" Runat="Server"/></th>
<th><asp:Label Text="Title" Width="80px" Runat="Server"/></th>
<th><asp:Label Text="Author" Width="70px" Runat="Server"/></th>
<th><asp:Label Text="Description" Width="150px" Runat="Server"/></th>
<th><asp:Label Text="Price" Width="40px" Runat="Server"/></th>
<th><asp:Label Text="Qty" Width="25px" Runat="Server"/></th>
<th><asp:Label Text="Sale" Width="42px" Runat="Server"/></th>
</tr>
</table>
</HeaderTemplate>
<ItemTemplate>
<table id="Edit" border="1">
<tr>
<td><asp:Button Text="New" CommandName="New" Runat="Server"
Font-Size="7pt" Width="35px"/></td>
</tr>
</table>
</ItemTemplate>
<InsertItemTemplate>
<table id="Insert" border="1">
<tr>
<td nowrap>
<asp:Button Text="Insert" CommandName="Insert" Runat="Server"
Font-Size="7pt" Width="35px"/>
<asp:Button Text="Cancel" CommandName="Cancel" Runat="Server"
Font-Size="7pt" Width="35px"/></td>
<td><asp:TextBox id="AddBookID" Runat="Server"
Text='<%# Bind("BookID")% >'
Font-Size="8pt" Width="45" MaxLength="5"/></td>
<td><asp:DropDownList id="AddType" Runat="Server"
DataSourceID="TypeSource"
DateTextField="BookType"
DataValueField="BookType"
SelectedValue='<%# Bind("BookType") %>'
Font-Size="8pt" Width="78"/></td>
<td><asp:TextBox id="AddTitle" Runat="Server"
Text='<%# Bind("BookTitle") %>'
Font-Size="8pt" Width="80"/></td>
<td><asp:TextBox id="AddAuthor" Runat="Server"
Text='<%# Bind("BookAuthor") %>'
Font-Size="8pt" Width="70"/></td>
<td><asp:TextBox id="AddDescription" Runat="Server"
Text='<%# Bind("BookDescription") %>'
TextMode="MultiLine" Rows="2" Font-Name="Arial"
Font-Size="8pt" Width="150"/></td>
<td><asp:TextBox id="AddPrice" Runat="Server"
Text='<%# Bind("BookPrice") %>'
Font-Size="8pt" Width="40" MaxLength="6"
Style="text-align:right"/></td>
<td><asp:TextBox id="AddQuantity" Runat="Server"
Text='<%# Bind("BookQty") %>'
Font-Size="8pt" Width="25" MaxLength="2"
Style="text-align:right"/></td>
<td style="text-align:center">
<asp:CheckBox id="AddSale" Runat="Server"
Checked='<%# Bind("ItemSale") %>' Width="40"/></td>
</tr>
</table>
</InsertItemTemplate>
</asp:FormView>
Listing 9-44. Code for FormView used with a master GridView.
The FormView's ItemTemplate, where normally a selected record is displayed, is used instead
to display only the "New" command button for record insertion. Its InsertItemTemplate contains related
"Insert" and "Cancel" buttons along with empty fields for data entry for a new record. Here is
where the FormView provides layout flexibility to match its display with that of the companion
GridView. Also, by placing all elements inside <table> tags,
provision is made for their exact sizing and placement.
Coding the GridView
The GridView, like the FormView, requires two AccessDataSource controls. The one shown below
services selection, updating, and deletion of records. A DeleteCommand
is not included since it is composed in a separate subprogram. The second AccessDataSource
required to populate the DropDownList of book types is the same one used for the FormView.
<asp:AccessDataSource id="EditSource" Runat="Server"
DataFile="../Databases/BooksDB.mdb"
SelectCommand="SELECT * FROM Books ORDER BY BookID"
UpdateCommand="UPDATE Books SET BookType=@BookType, BookTitle=@BookTitle,
BookAuthor=@BookAuthor, BookDescription=@BookDescription,
BookPrice=@BookPrice, BookQty=@BookQty, BookSale=@BookSale
WHERE BookID=@BookID"
/>
Listing 9-45. AccessDataSource for master GridView.
Coding for the GridView is shown below. Notice that all fields are defined explicitly
as server controls located inside TemplateFields for precise sizing and arrangement to
match the layout of the FormView. Editing buttons are Button controls configured
as command buttons for the RowUpdating, RowUpdated, and RowDeleting events.
<asp:GridView id="EditGrid" DataSourceID="EditSource" Runat="Server"
AutoGenerateColumns="False"
DataKeyNames="BookID"
ShowHeader="False"
AllowPaging="True"
PageSize="5"
EditRowStyle-BackColor="#FFFF00"
PagerStyle-BackColor="#E0E0E0"
RowStyle-VerticalAlign="Top"
RowStyle-Font-Size="10pt"
OnRowUpdating="Validate_Update_Data"
OnRowUpdated="Update_Record"
OnRowDeleting="Confirm_Delete">
<Columns>
<asp:TemplateField
ItemStyle-Wrap="False">
<ItemTemplate>
<asp:Button Text="Edit" CommandName="Edit" Runat="Server"
Font-Size="7pt" Width="35px"/>
<asp:Button Text="Delete" CommandName="Delete" Runat="Server"
Font-Size="7pt" Width="35px"/>
</ItemTemplate>
<EditItemTemplate>
<asp:Button Text="Update" CommandName="Update" Runat="Server"
Font-Size="7pt" Width="35px"/>
<asp:Button Text="Cancel" CommandName="Cancel" Runat="Server"
Font-Size="7pt" Width="35px"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label Text='<%# Eval("BookID") %>' Runat="Server"
Width="45"/>
</ItemTemplate>
<EditItemTemplate>
<asp:Label Text='<%# Eval("BookID") %>' Runat="Server"
Width="45"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label Text='<%# Eval("BookType") %>' Runat="Server"
Width="80"/>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList id="EditType" Runat="Server"
DataSourceID="TypeSource"
DateTextField="BookType"
DataValueField="BookType"
SelectedValue='<%# Bind("BookType") %>'
Font-Size="8pt"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label Text='<%# Eval("BookTitle") %>' Runat="Server"
Width="80"/>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id="EditTitle" Runat="Server"
Text='<%# Bind("BookTitle") %>'
Width="80" Font-Size="8pt"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label Text='<%# Eval("BookAuthor") %>' Runat="Server"
Width="70"/>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id="EditAuthor" Runat="Server"
Text='<%# Bind("BookAuthor") %>'
Width="70" Font-Size="8pt"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Panel Width="150" Height="30" ScrollBars="Vertical"
Runat="Server">
<asp:Label Text='<%# Eval("BookDescription") %>' Runat="Server"/>
</asp:Panel>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id="EditDescription" Runat="Server"
Text='<%# Bind("BookDescription") %>'
TextMode="MultiLine" Rows="2" Font-Name="Arial"
Width="150" Font-Size="8pt"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField
ItemStyle-HorizontalAlign="Right">
<ItemTemplate>
<asp:Label Text='<%# String.Format("{0:N}", Eval("BookPrice")) %>'
Width="40" Runat="Server"/>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id="EditPrice" Runat="Server"
Text='<%# Bind("BookPrice") %>'
Font-Size="8pt" Width="40" MaxLength="6"
Style="text-align:right"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField
ItemStyle-HorizontalAlign="Right">
<ItemTemplate>
<asp:Label Text='<%# String.Format("{0:D}", Eval("BookQty")) %>'
Width="25" Runat="Server"/>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id="EditQty" Runat="Server"
Text='<%# Bind("BookQty") %>'
Font-Size="8pt" Width="25" MaxLength="2"
Style="text-align:right"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField
ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox Checked='<%# Eval("BookSale") %>' Runat="Server"
Enabled="False" Width="40"/>
</ItemTemplate>
<EditItemTemplate>
<asp:CheckBox id="EditSale" Runat="Server"
Checked='<%# Bind("BookSale") %>'
Width="40"/>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Listing 9-46. Code for master GridView.
Scripting the Controls
Subprograms called from both the FormView and GridView are shown below. This coding should
be familiar from previous scripts implementing the same functionality.
<%@ Import Namespace="System.Drawing" %>
<SCRIPT Runat="Server">
Sub Validate_Update_Data (Src As Object, Args As GridViewUpdateEventArgs)
If Args.NewValues("BookTitle") = "" Then
Args.Cancel = True
EditMSG.Text = "• Missing title"
End If
If Args.NewValues("BookAuthor") = "" Then
Args.Cancel = True
EditMSG.Text = "• Missing author"
End If
If Args.NewValues("BookDescription") = "" Then
Args.Cancel = True
EditMSG.Text = "• Missing description"
End If
If Not IsNumeric(Args.NewValues("BookPrice")) Then
Args.Cancel = True
EditMSG.Text = "• Price not numeric"
Else
If Args.NewValues("BookPrice") < 0 _
OR Args.NewValues("BookPrice") > 200 Then
Args.Cancel = True
EditMSG.Text = "• Price is out of range"
End If
End If
If Not IsNumeric(Args.NewValues("BookQty")) Then
Args.Cancel = True
EditMSG.Text = "• Quantity not numeric"
Else
If Args.NewValues("BookQty") < 0 Then
Args.Cancel = True
EditMSG.Text = "• Quantity is out of range"
End If
End If
End Sub
Sub Update_Record (Src As Object, Args As GridViewUpdatedEventArgs)
EditMSG.Text = "• Record " & Args.Keys("BookID") & " updated"
End Sub
Sub Validate_Insert_Data (Src As Object, Args As FormViewInsertEventArgs)
If Args.Values("BookID") = "" Then
Args.Cancel = True
EditMSG.Text = "• Missing BookID"
End If
If Args.Values("BookTitle") = "" Then
Args.Cancel = True
EditMSG.Text = "• Missing title"
End If
If Args.Values("BookAuthor") = "" Then
Args.Cancel = True
EditMSG.Text = "• Missing author"
End If
If Args.Values("BookDescription") = "" Then
Args.Cancel = True
EditMSG.Text = "• Missing description"
End If
If Not IsNumeric(Args.Values("BookPrice")) Then
Args.Cancel = True
EditMSG.Text = "• Price not numeric"
Else
If Args.Values("BookPrice") < 0 _
OR Args.Values("BookPrice") > 200 Then
Args.Cancel = True
EditMSG.Text = "• Price out of range"
End If
End If
If Not IsNumeric(Args.Values("BookQty")) Then
Args.Cancel = True
EditMSG.Text = "• Quantity not numeric"
Else
If Args.Values("BookQty") < 0 Then
Args.Cancel = True
EditMSG.Text = "• Quantity out of range"
End If
End If
End Sub
Sub Insert_Record (Src As Object, Args As FormViewInsertedEventArgs)
EditGrid.DataBind()
EditMSG.Text = "• Record " & Args.Values("BookID") & " added"
End Sub
Sub Confirm_Delete (Src As Object, Args As GridViewDeleteEventArgs)
Args.Cancel = True
ConfirmDelete.Visible = True
Dim Row As GridViewRow = EditGrid.Rows(Args.RowIndex)
Row.BackColor = Color.FromName("#FF3333")
Row.ForeColor = Color.FromName("#FFFFFF")
ViewState("RowIndex") = Args.RowIndex
ViewState("BookID") = Args.Keys("BookID")
End Sub
Sub Delete_Record (Src As Object, Args As EventArgs)
EditSource.DeleteCommand = "DELETE FROM Books WHERE " & _
BookID = '" & ViewState("BookID") & "'"
EditSource.Delete()
Dim Row As GridViewRow = EditGrid.Rows(ViewState("RowIndex"))
Row.BackColor = Color.FromName("#FFFFFF")
Row.ForeColor = Color.FromName("#000000")
EditMSG.Text = "• Record " & ViewState("BookID") & " deleted"
End Sub
Sub Cancel_Delete (Src As Object, Args As EventArgs)
Dim Row As GridViewRow = EditGrid.Rows(ViewState("RowIndex"))
Row.BackColor = Color.FromName("#FFFFFF")
Row.ForeColor = Color.Fromname("#000000")
ConfirmDelete.Visible = False
End Sub
</SCRIPT>
Listing 9-47. Script to validate and update records through master/detail GridView/FormView.
It is noteworthy that clicking edit buttons highlights the affected row with a background
color giving a visual clue to the operation: green for inserting, yellow for updating, and
red for deleting. For the FormView, this row styling is handled by coding the
InsertRowStyle-BackColor="#00EE00" property, for the
GridView by coding the EditRowStyle-BackColor="#FFFF00"
property. For a GridView delete operation, however, there is no comparable row styling
property. This is because, normally, a record is immediately deleted with no editing row
appearing for styling. By trapping the RowDeleting event prior to deletion, though, the
normal ItemTemplate row can be singled out for highlighting.
Locating GridView Rows
Highlighting the GridView row of the record marked for deletion takes place in the
three subprograms associated with record deletion: Confirm_Delete,
Delete_Record, and Cancel_Delete.
The technique involves determining on which row the "Delete" button was clicked and styling
that row with a background color.
For a subprogram called by a GridView command button, its argument supplies an index
(beginning with 0) of the row on which a clicked button appears (Args.RowIndex
in the current subprograms). This index is used to identify this row from among
the GridView's Rows collection and to assign it to a
GridViewRow object. This object is then highlighted with
background and foreground colors. Code to locate and highlight a clicked row when the
Confirm_Delete subprogram is called on a click of the "Delete" button is reproduced below.
Sub Confirm_Delete (Src As Object, Args As GridViewDeleteEventArgs)
Args.Cancel = True
ConfirmDelete.Visible = True
Dim Row As GridViewRow = EditGrid.Rows(Args.RowIndex)
Row.BackColor = Color.FromName("#FF3333")
Row.ForeColor = Color.FromName("#FFFFFF")
ViewState("RowIndex") = Args.RowIndex
ViewState("BookID") = Args.Keys("BookID")
End Sub
Listing 9-48. Finding and saving a reference to a GridView row.
Since subsequent Delete_Record and Cancel_Delete
subprograms are called outside the context of the GridView (they are not called by GridView command
buttons but by independent "Yes" and "No" buttons), a RowIndex is not
available to these subprograms to change the row background color back to normal. Therefore, the
Confirm_Delete subprogram saves the current RowIndex
value in a View State variable, ViewState("RowIndex"). This
row identifier is then used in the Delete_Record and
Cancel_Delete subprograms to reset the row's background color. Affected statements in
these two subprograms are repeated below.
Sub Delete_Record (Src As Object, Args As EventArgs)
EditSource.DeleteCommand = "DELETE FROM Books WHERE " & _
BookID = '" & ViewState("BookID") & "'"
EditSource.Delete()
Dim Row As GridViewRow = EditGrid.Rows(ViewState("RowIndex"))
Row.BackColor = Color.FromName("#FFFFFF")
Row.ForeColor = Color.FromName("#000000")
EditMSG.Text = "• Record " & ViewState("BookID") & " deleted"
End Sub
Sub Cancel_Delete (Src As Object, Args As EventArgs)
Dim Row As GridViewRow = EditGrid.Rows(ViewState("RowIndex"))
Row.BackColor = Color.FromName("#FFFFFF")
Row.ForeColor = Color.Fromname("#000000")
ConfirmDelete.Visible = False
End Sub
Listing 9-49. Styling a GridView row.
It requires quite a bit of trial and error to align a FormView with a GridView in the
above manner. However, if you have the patience, the combination makes a very effective
"master/detail" editing form that can be adapted to many editing needs.