<asp:TemplateField> Control
GridView controls such as <asp:BoundField>,
<asp:ImageField>, and <asp:HyperLinkField> can be used
only to display a named data field from a data source. However, a GridView also can contain columns
of data that do not appear in the data source. For instance, you may wish to include a
column of calculated values. The displayed values are not contained in the data source, although
they may be derived from fields in the data source. To display data values that are not data fields,
an <asp:TemplateField> must be used. It also can be used in
place of a BoundField, ImageField, or HyperLinkField to display information from a data
source. Its general format is shown in Figure 7-12.
Figure 7-12. General format for <asp:TemplateField> of <asp:GridView> control.
An <asp:TemplateField> appears inside the
<Columns> tag of the GridView; it is composed of
<HeaderTemplate>, <ItemTemplate>,
<AlternatingItemTemplate>, and
<FooterTemplate> tags enclosing text strings, XHTML tags, and server controls
to format these areas of the column. Not all of these tags need to be coded, but you will need an
<ItemTemplate> tag to display data values.
HeaderStyle, ItemStyle, and FooterStyle server stylings can be applied only through the
<asp:TemplateField> control. They cannot be applied through
the individual templates. You can, however, include CSS style sheets inside the templates to
apply styles directly to enclosed text and XHTML elements.
In the following table, a calculated column gives the inventory amounts of selected books
from the BooksDB.mdb database. A final footer line shows the total
of these calculated amounts. The individual and total book amounts are not fields in the
Books table, but they can be derived from fields in the table.
Inventory Valuation - Hardware Books
| ID | Title | Book Description | Price | Qty | Amount |
| HW111 | How Computers Work |
How Computers Work, 7th Edition, has been one of the bestselling computer books for the last 10 years. This four-color visual tutorial is a must-have for any computer user, from novice to expert. The rich graphics and intricate details about the inner workings of computers have been admired for years by consumers, instructors, professionals, and readers of all ages. A fresh cover and interior provide the reader with superior usability and it is the most aesthetically-pleasing edition yet!
| $29.99 | 8 |
239.92
|
| HW222 | Upgrading and Repairing PCs |
Push your PC's performance to the limit. Know the differences between: Pentium II, Pentium MMX, Pentium Pro, and earlier CPU chips and choose the best chip for your needs; understand compatibility and feature sets of processor upgrade sockets, motherboards, and chipsets; use Universal Serial Bus ports and devices to simplify peripheral installation, configuration, and improve performance; squeeze the most performance, life, and reliability out of your hard drives; prevent memory headaches: pick the right speed and type of SIMMs and DIMMs, run more programs at once, and work with bigger files; and integrate hot new hardware including 3D graphics accelerators, fast SDRAM memory, Zoomed Video and CardBus PC Cards for your notebook, and NLX motherboards with support for Single Edge Contact processors and Accelerated Graphics Ports.
| $59.99 | 5 |
299.95
|
| HW333 | USB System Architecture |
Universal Serial Bus System Architecture, Second Edition, based on the 2.0 version of the Universal Serial Bus specification, provides in-depth coverage and a detailed discussion of USB. It focuses on the USB protocol, signaling environment, and electrical specifications, along with the hardware/software interaction required to configure and access USB devices.
| $49.99 | 1 |
49.99
|
| HW444 | Designing Embedded Hardware |
Designing Embedded Hardware is a book about designing small machines for embedded applications. There are many books on the market dedicated to writing code for particular microprocessors, or that stress the philosophy of embedded system design without providing any practical information. This book steers a middle path, telling you what you need to know to create your own products, and distilling much of the lore of embedded systems design into a single volume. It shows you how to build a complete embedded system, add peripherals, and connect your system to other devices.
| $44.95 | 3 |
134.85
|
| HW555 | Contemporary Logic Design |
Contemporary Logic Design introduces a wide range of software tools including schematic capture, logic simulation, Boolean minimization, multi-level minimization and state assignment. Links the traditional techniques of logic design (such as Karnaugh maps and breadboard techniques) with real-world design examples. Provides comprehensive, early coverage of programmable logic including ROMs, PALs, and PLAs. Includes a variety of examples, exercises, problems, and case studies that illustrate real design problems and challenge the reader to develop practical solutions using modern design tools.
| $102.95 | 2 |
205.90
|
| | | | | Total: |
$930.61
|
Figure 7-13. Using a Template column for calculated values in a GridView.
Binding Data Values to TemplateFields
A TemplateField, like a BoundField, can display values taken directly from a data source; it
can also display calculated values involving data fields, and it can display values returned from
function calls. In the case of binding a field from a data source to a TemplateField, the
Eval() method is used as the equivalent of using a DataField property in a BoundField.
Figure 7-14. General format for Eval() data binding method.
Code that appears between <%# and %>
symbols is called a binding expression. The expression is replaced by its derived value.
In the above format, the expression Eval("fieldname") evaluates
to a value contained in a named field in a data source bound to the control.
Assume, for instance, that the BookPrice field from
BooksDB.mdb were bound to and displayed in a TemplateField. The format for doing
so would be similar to the following.
<asp:TemplateField>
<HeaderTemplate>
Price
</HeaderTemplate>
<ItemTemplate>
<%# Eval("BookPrice") %>
</ItemTemplate>
</asp:TemplateField>
Listing 7-8. Binding a data value to a GridView template.
The binding expression <%# Eval("BookPrice") %> is replaced
by the actual data value of the BookPrice field for each row of the
GridView that corresponds with a database record.
Although a binding expression itself can appear inside an ItemTemplate, it is often assigned to
a server control to take advantage of the control's property settings. An alternative, and normally
preferred, method of displaying a bound field is through the Text property
of a Label control, as shown in the following recoding of the above TemplateField.
<asp:TemplateField
HeaderText="Price">
<ItemTemplate>
<asp:Label Font-Name="Verdana" Font-Size="10pt" Runat="Server"
Text='<%# Eval("BookPrice") %>'/>
</ItemTemplate>
</asp:TemplateField>
Listing 7-9. Binding a data value to a GridView server control.
The value of the bound data item is displayed in the ItemTemplate as in the previous example.
However, it also takes on any styling applied in the Label control through which it is displayed.
Note that the column heading is given by coding the HeaderText
property for the TemplateField. This is an alternative to coding a separate
<HeaderTemplate> tag as in the previous example.
Displaying Scrolling Fields
A GridView presents data fields along the rows of a table. Sometimes, though, the amount of data
is too large to fit comfortably inside a table cell. In the above example, the
BookDescription field is a case in point. If displayed in a BoundField, the size of
the field expands vertically to encompass the amount of text being displayed, making for a very
lengthy and awkward-looking table. A better solution is to display lengthy text fields inside
scrollable fields all of the same dimensions, as is done in the example.
A TemplateField can include a Label control inside a Panel control to create a scrollable
field. The Panel is given Width and Height
settings for the fixed size of the display area, along with the ScrollBars
property to introduce scroll bars. Text is bound to the Label control inside this scrollable area.
Below is shown code for the TemplateField used to display book descriptions in the example
GridView.
<asp:TemplateField
HeaderText="Book Description">
<ItemTemplate>
<asp:Panel Width="230px" Height="40px" ScrollBars="Vertical"
Runat="Server">
<asp:Label Font-Size="8pt" Font-Name="Verdana"
Text='<%# Eval("BookDescription") %>' Runat="Server"/>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
Listing 7-10. Creating scrollable text in a GridView column.
In the current example, ScrollBars is set to "Vertical"
to always display a vertical scroll bar whether needed or not to display the enclosed
text. An option is to set this property to "Auto" to display a vertical scroll
bar only if needed.
Binding Calculated Values
If data values for template columns are not taken directly from a data source, then scripting
is needed to supply these values. In the example GridView, the final column displays the calculated
value of the BookPrice field multiplied times the
BookQty field. One of the ways to supply these values is by including this calculation
inside a binding expression as shown by the following code.
<asp:TemplateField
HeaderText="Amount"
ItemStyle-HorizontalAlign="Right">
<ItemTemplate>
<asp:Label Text='<%# Eval("BookPrice") * Eval("BookQty") %>'
Runat="Server"/>
</ItemTemplate>
</asp:TemplateField>
Listing 7-11. Binding calculated expressions to a GridView.
For each row of the GridView, the BookPrice field from the database
row is multiplied by the BookQty field, and the resulting value is bound
to the ItemTemplate's enclosed Label. Formatting can be applied to the calculated
amountto the binding expressionusing either
Text='<%# FormatNumber(Eval("BookPrice") * Eval("BookQty"), 2) %>'
or
Text='<%# String.Format("{0:N2}", Eval("BookPrice") * Eval("BookQty")) %>'
Binding Functions
A second method to supply a calculated value for a TemplateField is to bind a value returned
from a Visual Basic function call. The function call appears inside a binding expression and is
replaced by its returned value. An alternative, for example, to including the above multiplication
itself inside a binding expression is to move the calculation to a function call and pass to it the
BookPrice and BookQty values to be
multiplied.
Function Get_Amount (Price As Decimal, Quantity As Integer)
Dim Amount As Decimal = Price * Quantity
Return String.Format("{0:N2}", Amount)
End Function
<asp:TemplateField
HeaderText="Amount"
ItemStyle-HorizontalAlign="Right">
<ItemTemplate>
<asp:Label Text='<%# Get_Amount(Eval("BookPrice"), Eval("BookQty")) %>'
Runat="Server"/>
</ItemTemplate>
</asp:TemplateField>
Listing 7-12. Binding functions to a GridView.
For each row of the GridView, the BookPrice and
BookQty values are passed to the Get_Amount() function. The function
returns variable Amount, whose calculated and formatted value is
displayed in the binding expression as replacement for the function call.
In the example GridView, not only does the final column display a calculated value for a
row, but the FooterTemplate displays the total of all calculated amounts. Therefore, two Visual
Basic functions are used. The Get_Amount() function is an expansion of
the one above in order to accumulate the calculated amount; the Get_Total()
function returns the final accumulated inventory total. The full script and GridView code for this
application are shown below.
<SCRIPT Runat="Server">
Dim Total As Decimal = 0.00
Function Get_Amount (Price As Decimal, Quantity As Integer)
Dim Amount As Decimal = Price * Quantity
Total += Amount
Return String.Format("{0:N2}", Amount)
End Function
Function Get_Total()
Return String.Format("{0:C}", Total)
End Function
</SCRIPT>
<form Runat="Server">
<asp:AccessDataSource id="BookSource" Runat="Server"
DataFile="../Databases/BooksDB.mdb"
SelectCommand="SELECT * FROM Books WHERE BookType='Hardware'
ORDER BY BookID"/>
<asp:GridView id="BookGrid" DataSourceID="BookSource" Runat="Server"
AutoGenerateColumns="False"
ShowFooter="True"
Caption="<b>Inventory Valuation - Hardware Books</b>"
CellPadding="3"
HeaderStyle-BackColor="#707070"
HeaderStyle-ForeColor="#FFFFFF"
RowStyle-Font-Name="Verdana"
RowStyle-Font-Size="8pt"
RowStyle-VerticalAlign="Top"
FooterStyle-BackColor="#707070"
FooterStyle-ForeColor="#FFFFFF"
FooterStyle-Font-Size="11pt">
<Columns>
<asp:BoundField
DataField="BookID"
HeaderText="ID"
FooterStyle-BorderWidth="0"/>
<asp:BoundField
DataField="BookTitle"
HeaderText="Title"
FooterStyle-BorderWidth="0"/>
<asp:TemplateField
HeaderText="Book Description">
<ItemTemplate>
<asp:Panel Width="230px" Height="40px" ScrollBars="Vertical"
Runat="Server">
<asp:Label Font-Size="8pt" Font-Name="Verdana" Runat="Server"
Text='<%# Eval("BookDescription") %>'/>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField
DataField="BookPrice"
HeaderText="Price"
ItemStyle-HorizontalAlign="Right"
HtmlEncode="False"
DataFormatString="{0:N2}"
FooterStyle-BorderWidth="0"/>
<asp:BoundField
DataField="BookQty"
HeaderText="Qty"
ItemStyle-HorizontalAlign="Right"
HtmlEncode="False"
DataFormatString="{0:D}"
FooterText="Total: "
FooterStyle-Font-Bold="True"
FooterStyle-BorderWidth="0"/>
<asp:TemplateField
HeaderText="Amount"
ItemStyle-HorizontalAlign="Right"
FooterStyle-Font-Size="10pt"
FooterStyle-HorizontalAlign="Right"
FooterStyle-Font-Bold="True"
FooterStyle-BorderWidth="0">
<ItemTemplate>
<asp:Label id="Amount" Runat="Server"
Text='<%# Get_Amount(Eval("BookPrice"), Eval("BookQty")) %>'/>
</ItemTemplate>
<FooterTemplate>
<asp:Label id="Total" Runat="Server"
Text='<%# Get_Total() %>'/>
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Listing 7-13. Code for example GridView with calculated columns.
BoundField columns are used to display the BookID,
BookTitle, BookPrice, and BookQty fields
directly from the available recordset. A TemplateField is needed for the amount column, which
displays the price field multiplied times the quantity field for each record. Also, this calculated
amount is summed to derive the total inventory value reported in the footer row of the column.
A global variable named Total is declared and initialized at the
beginning of the script. This variable serves as an accumulator for the inventory total. Function
Get_Amount() is passed two values, a price and a quantity from the
associated database record; these values are received by the function through its argument
list.
Within function Get_Amount(), the received
Price and Quantity values are multiplied to derive local variable
Amount. This amount is added to global variable Total
prior to returning it to the calling expression for display. Recall that a function call
is replaced by a returned value; therefore, the Amount value is
substituted for the calling statement. The numeric format string is applied to the returned
Amount to style it for display. As you can see, variable Total is necessarily a global variable. It cannot be declared inside
function Get_Amount() or it would be reinitialzed on each call and
never accumulate the calculated Amounts.
This processing is repeated for each of the database records in the data source. At the end of
processing, a footer row is added to the table to report the inventory
Total, which was accumulating with each function call to
Get_Amount(). The function call to Get_Total() simply returns
the currency-formatted value of variable Total, replacing the call with
the inventory total.
Incidentally, it is not necessary to call function Get_Total() to
display variable Total. Any global script variable can be bound
to a template simply by enclosing the variable name in a binding expression. Alternate coding for
the above FooterTemplate is shown below.
<FooterTemplate>
<asp:Label Text='<%# String.Format("{0:C}", Total) %>' Runat="Server"/>
</FooterTemplate>
Listing 7-14. Binding a variable to a GridView template.
You might notice in the example GridView that the footer row does not contain borders between
columns, leaving the impression that the footer is a single cell that spans the width of the
table. This is not the case, however. Separate columns still appear and cannot, in fact, be
spanned. The effect is produced by setting the BorderWidth property
of all footer columns to 0 pixels: FooterStyle-BorderWidth="0".
Displaying Pictures in Templates
A TemplateField can be used to display graphic images in a GridView column. In the following
example, an <asp:Image> control is coded inside an <ItemTemplate> and is bound to a reference to an image file. In
addition, an <asp:HyperLink> control appears in the template
to open the full-size image in a separate frame.
| ID | Title | Price | Picture |
| GR111 | Adobe Photoshop CS2 | $29.99 |

Full Size
|
| GR222 | Learning Web Design | $39.95 |

Full Size
|
| GR333 | Macromedia Flash Professional | $44.99 |

Full Size
|
| GR444 | Digital Photographer Handbook | $24.95 |

Full Size
|
| GR555 | Creating Motion Graphics | $59.95 |

Full Size
|
Figure 7-15. Using a Template column to display images and links in a GridView.
<asp:AccessDataSource id="BookSource" Runat="Server"
DataFile="../Databases/BooksDB.mdb"
SelectCommand="SELECT BookID, BookTitle, BookPrice FROM Books
WHERE BookType='Graphics' ORDER BY BookID"/>
<asp:GridView id="BookGrid" DataSourceID="BookSource" Runat="Server"
AutoGenerateColumns="False"
Style="float:left"
CellPadding="3"
HeaderStyle-BackColor="#707070"
HeaderStyle-ForeColor="#FFFFFF"
HeaderStyle-Font-size="11pt"
RowStyle-VerticalAlign="Top"
<Columns>
<asp:BoundField
DataField="BookID"
HeaderText="ID"/>
<asp:BoundField
DataField="BookTitle"
HeaderText="Title"/>
<asp:BoundField
DataField="BookPrice"
HeaderText="Price"
ItemStyle-HorizontalAlign="Right"
DataFormatString="{0:N2}"/>
<asp:TemplateField
HeaderText="Picture"
ItemStyle-Font-Size="9pt"
ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Image Width="40" Runat="Server"
AlternateText='<%# "Picture of " & Eval("BookID") %>'
ImageUrl='<%# "../BookPictures/" & Eval("BookID") & ".jpg" %>'/><br/>
<asp:HyperLink Text="Full Size" Target="PictureFrame" Runat="Server"
NavigateUrl='<%# "../BookPictures/" & Eval("BookID") & ".jpg" %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<iframe name="PictureFrame" style="width:130px; height:160px;
border:outset 5"></iframe>
Listing 7-15. Code for Template column to display images and links.
Recall from an earlier example that use of an <asp:ImageField>
control in a GridView does not permit resizing of the image. However, using an
<asp:Image> control in a TemplateField does permit its resizing during display. In
this case, its Width is set at 40 pixels with its height adjusted
automatically to maintain proportionality. An accompanying <asp:HyperLink>
control appears below the image to display clickable text to open the full-size picture
in a floating frame.
Since book pictures have names matching their BookIDs,
their directory path concatenated with the BookID
concatenated with the string ".jpg" produces the URL for
the associated picture. The ImageUrl property of the
<asp:Image> control and the NavigateUrl property of the
<asp:HyperLink> control are binding expressions using this
URL, the former to display the picture and the latter to target it to the
<iframe>. The AlternateText property of the Image control
includes a binding expression to the BookID for its display as
alternate text on mouse-over of the image.