08.12.2012 Views

Using TemplateFields in the GridView Control - ASP.net

Using TemplateFields in the GridView Control - ASP.net

Using TemplateFields in the GridView Control - ASP.net

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

1 of 17<br />

This tutorial is part of a set. F<strong>in</strong>d out more about data access with <strong>ASP</strong>.NET <strong>in</strong> <strong>the</strong> Work<strong>in</strong>g with Data <strong>in</strong><br />

<strong>ASP</strong>.NET 2.0 section of <strong>the</strong> <strong>ASP</strong>.NET site at http://www.asp.<strong>net</strong>/learn/dataaccess/default.aspx.<br />

Work<strong>in</strong>g with Data <strong>in</strong> <strong>ASP</strong>.NET 2.0 :: <strong>Us<strong>in</strong>g</strong><br />

<strong>TemplateFields</strong> <strong>in</strong> <strong>the</strong> <strong>GridView</strong> <strong>Control</strong><br />

Download <strong>the</strong> code for this sample<br />

Click here for <strong>the</strong> previous tutorial<br />

Introduction<br />

The <strong>GridView</strong> is composed of a set of fields that <strong>in</strong>dicate what properties from <strong>the</strong> DataSource are to be<br />

<strong>in</strong>cluded <strong>in</strong> <strong>the</strong> rendered output along with how <strong>the</strong> data will be displayed. The simplest field type is <strong>the</strong><br />

BoundField, which displays a data value as text. O<strong>the</strong>r field types display <strong>the</strong> data us<strong>in</strong>g alternate HTML<br />

elements. The CheckBoxField, for example, renders as a checkbox whose checked state depends on <strong>the</strong> value<br />

of a specified data field; <strong>the</strong> ImageField renders an image whose image source is based upon a specified data<br />

field. Hyperl<strong>in</strong>ks and buttons whose state depends on an underly<strong>in</strong>g data field value can be rendered us<strong>in</strong>g <strong>the</strong><br />

HyperL<strong>in</strong>kField and ButtonField field types.<br />

While <strong>the</strong> CheckBoxField, ImageField, HyperL<strong>in</strong>kField, and ButtonField field types allow for an alternate view<br />

of <strong>the</strong> data, <strong>the</strong>y still are fairly limited with respect to formatt<strong>in</strong>g. A CheckBoxField can only display a s<strong>in</strong>gle<br />

checkbox, whereas an ImageField can only display a s<strong>in</strong>gle image. What if a particular field needs to display<br />

some text, a checkbox, and an image, all based upon different data field values? Or what if we wanted to<br />

display <strong>the</strong> data us<strong>in</strong>g a Web control o<strong>the</strong>r than <strong>the</strong> CheckBox, Image, HyperL<strong>in</strong>k, or Button? Fur<strong>the</strong>rmore,<br />

<strong>the</strong> BoundField limits its display to a s<strong>in</strong>gle data field. What if we wanted to show two or more data field<br />

values <strong>in</strong> a s<strong>in</strong>gle <strong>GridView</strong> column?<br />

To accommodate this level of flexibility <strong>the</strong> <strong>GridView</strong> offers <strong>the</strong> TemplateField, which renders us<strong>in</strong>g a<br />

template. A template can <strong>in</strong>clude a mix of static HTML, Web controls, and datab<strong>in</strong>d<strong>in</strong>g syntax. Fur<strong>the</strong>rmore,<br />

<strong>the</strong> TemplateField has a variety of templates that can be used to customize <strong>the</strong> render<strong>in</strong>g for different<br />

situations. For example, <strong>the</strong> ItemTemplate is used by default to render <strong>the</strong> cell for each row, but <strong>the</strong><br />

EditItemTemplate template can be used to customize <strong>the</strong> <strong>in</strong>terface when edit<strong>in</strong>g data.<br />

In this tutorial we'll exam<strong>in</strong>e how to use <strong>the</strong> TemplateField to achieve a greater degree of customization with<br />

<strong>the</strong> <strong>GridView</strong> control. In <strong>the</strong> preced<strong>in</strong>g tutorial we saw how to customize <strong>the</strong> formatt<strong>in</strong>g based on <strong>the</strong><br />

underly<strong>in</strong>g data us<strong>in</strong>g <strong>the</strong> DataBound and RowDataBound event handlers. Ano<strong>the</strong>r way to customize <strong>the</strong><br />

formatt<strong>in</strong>g based on <strong>the</strong> underly<strong>in</strong>g data is by call<strong>in</strong>g formatt<strong>in</strong>g methods from with<strong>in</strong> a template. We'll look at<br />

this technique <strong>in</strong> this tutorial as well.<br />

For this tutorial we will use <strong>TemplateFields</strong> to customize <strong>the</strong> appearance of a list of employees. Specifically,<br />

we'll list all of <strong>the</strong> employees, but will display <strong>the</strong> employee's first and last names <strong>in</strong> one column, <strong>the</strong>ir hire date<br />

<strong>in</strong> a Calendar control, and a status column that <strong>in</strong>dicates how many days <strong>the</strong>y've been employed at <strong>the</strong><br />

company.


2 of 17<br />

Figure 1: Three <strong>TemplateFields</strong> are Used to Customize <strong>the</strong> Display<br />

Step 1: B<strong>in</strong>d<strong>in</strong>g <strong>the</strong> Data to <strong>the</strong> <strong>GridView</strong><br />

In report<strong>in</strong>g scenarios where you need to use <strong>TemplateFields</strong> to customize <strong>the</strong> appearance, I f<strong>in</strong>d it easiest to<br />

start by creat<strong>in</strong>g a <strong>GridView</strong> control that conta<strong>in</strong>s just BoundFields first and <strong>the</strong>n to add new <strong>TemplateFields</strong><br />

or convert <strong>the</strong> exist<strong>in</strong>g BoundFields to <strong>TemplateFields</strong> as needed. Therefore, let's start this tutorial by add<strong>in</strong>g a<br />

<strong>GridView</strong> to <strong>the</strong> page through <strong>the</strong> Designer and b<strong>in</strong>d<strong>in</strong>g it to an ObjectDataSource that returns <strong>the</strong> list of<br />

employees. These steps will create a <strong>GridView</strong> with BoundFields for each of <strong>the</strong> employee fields.<br />

Open <strong>the</strong> <strong>GridView</strong>TemplateField.aspx page and drag a <strong>GridView</strong> from <strong>the</strong> Toolbox onto <strong>the</strong> Designer.<br />

From <strong>the</strong> <strong>GridView</strong>'s smart tag choose to add a new ObjectDataSource control that <strong>in</strong>vokes <strong>the</strong><br />

EmployeesBLL class's GetEmployees() method.


3 of 17<br />

Figure 2: Add a New ObjectDataSource <strong>Control</strong> that Invokes <strong>the</strong> GetEmployees() Method<br />

B<strong>in</strong>d<strong>in</strong>g <strong>the</strong> <strong>GridView</strong> <strong>in</strong> this manner will automatically add a BoundField for each of <strong>the</strong> employee properties:<br />

EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, and Country. For this report let's not<br />

bo<strong>the</strong>r with display<strong>in</strong>g <strong>the</strong> EmployeeID, ReportsTo, or Country properties. To remove <strong>the</strong>se BoundFields<br />

you can:<br />

Use <strong>the</strong> Fields dialog box – click on <strong>the</strong> Edit Columns l<strong>in</strong>k from <strong>the</strong> <strong>GridView</strong>'s smart tag to br<strong>in</strong>g up<br />

this dialog box. Next, select <strong>the</strong> BoundFields from <strong>the</strong> lower left list and click <strong>the</strong> red X button to<br />

remove <strong>the</strong> BoundField.<br />

Edit <strong>the</strong> <strong>GridView</strong>'s declarative syntax by hand – from <strong>the</strong> Source view, delete <strong>the</strong> <br />

element for <strong>the</strong> BoundField you wish to remove.<br />

After you have removed <strong>the</strong> EmployeeID, ReportsTo, and Country BoundFields, your <strong>GridView</strong>'s markup<br />

should look like:<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Take a moment to view our progress <strong>in</strong> a browser. At this po<strong>in</strong>t you should see a table with a record for each<br />

employee and four columns: one for <strong>the</strong> employee's last name, one for <strong>the</strong>ir first name, one for <strong>the</strong>ir title, and<br />

one for <strong>the</strong>ir hire date.


4 of 17<br />

Figure 3: The LastName, FirstName, Title, and HireDate Fields are Displayed for Each Employee<br />

Step 2: Display<strong>in</strong>g <strong>the</strong> First and Last Names <strong>in</strong> a<br />

S<strong>in</strong>gle Column<br />

Currently, each employee's first and last names are displayed <strong>in</strong> a separate column. It might be nice to comb<strong>in</strong>e<br />

<strong>the</strong>m <strong>in</strong>to a s<strong>in</strong>gle column <strong>in</strong>stead. To accomplish this we need to use a TemplateField. We can ei<strong>the</strong>r add a<br />

new TemplateField, add to it <strong>the</strong> needed markup and datab<strong>in</strong>d<strong>in</strong>g syntax, and <strong>the</strong>n delete <strong>the</strong> FirstName and<br />

LastName BoundFields, or we can convert <strong>the</strong> FirstName BoundField <strong>in</strong>to a TemplateField, edit <strong>the</strong><br />

TemplateField to <strong>in</strong>clude <strong>the</strong> LastName value, and <strong>the</strong>n remove <strong>the</strong> LastName BoundField.<br />

Both approaches <strong>net</strong> <strong>the</strong> same result, but personally I like convert<strong>in</strong>g BoundFields to <strong>TemplateFields</strong> when<br />

possible because <strong>the</strong> conversion automatically adds an ItemTemplate and EditItemTemplate with Web<br />

controls and datab<strong>in</strong>d<strong>in</strong>g syntax to mimic <strong>the</strong> appearance and functionality of <strong>the</strong> BoundField. The benefit is<br />

that we'll need to do less work with <strong>the</strong> TemplateField as <strong>the</strong> conversion process will have performed some of<br />

<strong>the</strong> work for us.<br />

To convert an exist<strong>in</strong>g BoundField <strong>in</strong>to a TemplateField, click on <strong>the</strong> Edit Columns l<strong>in</strong>k from <strong>the</strong> <strong>GridView</strong>'s<br />

smart tag, br<strong>in</strong>g<strong>in</strong>g up <strong>the</strong> Fields dialog box. Select <strong>the</strong> BoundField to convert from <strong>the</strong> list <strong>in</strong> <strong>the</strong> lower left<br />

corner and <strong>the</strong>n click <strong>the</strong> "Convert this field <strong>in</strong>to a TemplateField" l<strong>in</strong>k <strong>in</strong> <strong>the</strong> bottom right corner.


5 of 17<br />

Figure 4: Convert a BoundField Into a TemplateField from <strong>the</strong> Fields Dialog Box<br />

Go ahead and convert <strong>the</strong> FirstName BoundField <strong>in</strong>to a TemplateField. After this change <strong>the</strong>re's no<br />

perceptive difference <strong>in</strong> <strong>the</strong> Designer. This is because convert<strong>in</strong>g <strong>the</strong> BoundField <strong>in</strong>to a TemplateField creates<br />

a TemplateField that ma<strong>in</strong>ta<strong>in</strong>s <strong>the</strong> look and feel of <strong>the</strong> BoundField. Despite <strong>the</strong>re be<strong>in</strong>g no visual difference at<br />

this po<strong>in</strong>t <strong>in</strong> <strong>the</strong> Designer, this conversion process has replaced <strong>the</strong> BoundField's declarative syntax ­<br />

­ with <strong>the</strong> follow<strong>in</strong>g TemplateField syntax:<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

As you can see, <strong>the</strong> TemplateField consists of two templates – an ItemTemplate that has a Label whose Text<br />

property is set to <strong>the</strong> value of <strong>the</strong> FirstName data field, and an EditItemTemplate with a TextBox control<br />

whose Text property is also set to <strong>the</strong> FirstName data field. The datab<strong>in</strong>d<strong>in</strong>g syntax ­ ­ <strong>in</strong>dicates that <strong>the</strong> data field fieldName is bound to <strong>the</strong> specified Web control<br />

property.<br />

To add <strong>the</strong> LastName data field value to this TemplateField we need to add ano<strong>the</strong>r Label Web control <strong>in</strong> <strong>the</strong><br />

ItemTemplate and b<strong>in</strong>d its Text property to LastName. This can be accomplished ei<strong>the</strong>r by hand or through<br />

<strong>the</strong> Designer. To do it by hand, simply add <strong>the</strong> appropriate declarative syntax to <strong>the</strong> ItemTemplate:<br />

<br />

<br />


6 of 17<br />

<br />

<br />

<br />

<br />

<br />

<br />

To add it through <strong>the</strong> Designer, click on <strong>the</strong> Edit Templates l<strong>in</strong>k from <strong>the</strong> <strong>GridView</strong>'s smart tag. This will<br />

display <strong>the</strong> <strong>GridView</strong>'s template edit<strong>in</strong>g <strong>in</strong>terface. In this <strong>in</strong>terface's smart tag is a list of <strong>the</strong> templates <strong>in</strong> <strong>the</strong><br />

<strong>GridView</strong>. S<strong>in</strong>ce we only have one TemplateField at this po<strong>in</strong>t, <strong>the</strong> only templates listed <strong>in</strong> <strong>the</strong> drop­down list<br />

are those templates for <strong>the</strong> FirstName TemplateField along with <strong>the</strong> EmptyDataTemplate and<br />

PagerTemplate. The EmptyDataTemplate template, if specified, is used to render <strong>the</strong> <strong>GridView</strong>'s output if<br />

<strong>the</strong>re are no results <strong>in</strong> <strong>the</strong> data bound to <strong>the</strong> <strong>GridView</strong>; <strong>the</strong> PagerTemplate, if specified, is used to render <strong>the</strong><br />

pag<strong>in</strong>g <strong>in</strong>terface for a <strong>GridView</strong> that supports pag<strong>in</strong>g.<br />

Figure 5: The <strong>GridView</strong>'s Templates Can Be Edited Through <strong>the</strong> Designer<br />

To also display <strong>the</strong> LastName <strong>in</strong> <strong>the</strong> FirstName TemplateField drag <strong>the</strong> Label control from <strong>the</strong> Toolbox <strong>in</strong>to<br />

<strong>the</strong> FirstName TemplateField's ItemTemplate <strong>in</strong> <strong>the</strong> <strong>GridView</strong>'s template edit<strong>in</strong>g <strong>in</strong>terface.


7 of 17<br />

Figure 6: Add a Label Web <strong>Control</strong> to <strong>the</strong> FirstName TemplateField's ItemTemplate<br />

At this po<strong>in</strong>t <strong>the</strong> Label Web control added to <strong>the</strong> TemplateField has its Text property set to "Label". We need<br />

to change this so that this property is bound to <strong>the</strong> value of <strong>the</strong> LastName data field <strong>in</strong>stead. To accomplish<br />

this click on <strong>the</strong> Label control's smart tag and choose <strong>the</strong> Edit DataB<strong>in</strong>d<strong>in</strong>gs option.<br />

Figure 7: Choose <strong>the</strong> Edit DataB<strong>in</strong>d<strong>in</strong>gs Option from <strong>the</strong> Label's Smart Tag<br />

This will br<strong>in</strong>g up <strong>the</strong> DataB<strong>in</strong>d<strong>in</strong>gs dialog box. From here you can select <strong>the</strong> property to participate <strong>in</strong><br />

datab<strong>in</strong>d<strong>in</strong>g from <strong>the</strong> list on <strong>the</strong> left and choose <strong>the</strong> field to b<strong>in</strong>d <strong>the</strong> data to from <strong>the</strong> drop­down list on <strong>the</strong><br />

right. Choose <strong>the</strong> Text property from <strong>the</strong> left and <strong>the</strong> LastName field from <strong>the</strong> right and click OK.


8 of 17<br />

Figure 8: B<strong>in</strong>d <strong>the</strong> Text Property to <strong>the</strong> LastName Data Field<br />

Note: The DataB<strong>in</strong>d<strong>in</strong>gs dialog box allows you to <strong>in</strong>dicate whe<strong>the</strong>r to perform two­way datab<strong>in</strong>d<strong>in</strong>g. If you<br />

leave this unchecked, <strong>the</strong> datab<strong>in</strong>d<strong>in</strong>g syntax will be used <strong>in</strong>stead of . Ei<strong>the</strong>r approach is f<strong>in</strong>e for this tutorial. Two­way datab<strong>in</strong>d<strong>in</strong>g becomes important<br />

when <strong>in</strong>sert<strong>in</strong>g and edit<strong>in</strong>g data. For simply display<strong>in</strong>g data, however, ei<strong>the</strong>r approach will work equally well.<br />

We'll discuss two­way datab<strong>in</strong>d<strong>in</strong>g <strong>in</strong> detail <strong>in</strong> future tutorials.<br />

Take a moment to view this page through a browser. As you can see, <strong>the</strong> <strong>GridView</strong> still <strong>in</strong>cludes four<br />

columns; however, <strong>the</strong> FirstName column now lists both <strong>the</strong> FirstName and LastName data field values.<br />

Figure 9: Both <strong>the</strong> FirstName and LastName Values are Shown <strong>in</strong> a S<strong>in</strong>gle Column<br />

To complete this first step, remove <strong>the</strong> LastName BoundField and rename <strong>the</strong> FirstName TemplateField's<br />

HeaderText property to "Name". After <strong>the</strong>se changes <strong>the</strong> <strong>GridView</strong>'s declarative markup should look like <strong>the</strong><br />

follow<strong>in</strong>g:<br />

<br />


9 of 17<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Figure 10: Each Employee's First and Last Names are Displayed <strong>in</strong> One Column<br />

Step 3: <strong>Us<strong>in</strong>g</strong> <strong>the</strong> Calendar <strong>Control</strong> to Display <strong>the</strong> HiredDate Field<br />

Display<strong>in</strong>g a data field value as text <strong>in</strong> a <strong>GridView</strong> is as simple as us<strong>in</strong>g a BoundField. For certa<strong>in</strong> scenarios,<br />

however, <strong>the</strong> data is best expressed us<strong>in</strong>g a particular Web control <strong>in</strong>stead of just text. Such customization of<br />

<strong>the</strong> display of data is possible with <strong>TemplateFields</strong>. For example, ra<strong>the</strong>r than display <strong>the</strong> employee's hire date<br />

as text, we could show a calendar (us<strong>in</strong>g <strong>the</strong> Calendar control) with <strong>the</strong>ir hire date highlighted.<br />

To accomplish this, start by convert<strong>in</strong>g <strong>the</strong> HiredDate BoundField <strong>in</strong>to a TemplateField. Simply go to <strong>the</strong><br />

<strong>GridView</strong>'s smart tag and click <strong>the</strong> Edit Columns l<strong>in</strong>k, br<strong>in</strong>g<strong>in</strong>g up <strong>the</strong> Fields dialog box. Select <strong>the</strong> HiredDate<br />

BoundField and click "Convert this field <strong>in</strong>to a TemplateField."


10 of 17<br />

Figure 11: Convert <strong>the</strong> HiredDate BoundField Into a TemplateField<br />

As we saw <strong>in</strong> Step 2, this will replace <strong>the</strong> BoundField with a TemplateField that conta<strong>in</strong>s an ItemTemplate<br />

and EditItemTemplate with a Label and TextBox whose Text properties are bound to <strong>the</strong> HiredDate value<br />

us<strong>in</strong>g <strong>the</strong> datab<strong>in</strong>d<strong>in</strong>g syntax .<br />

To replace <strong>the</strong> text with a Calendar control, edit <strong>the</strong> template by remov<strong>in</strong>g <strong>the</strong> Label and add<strong>in</strong>g a Calendar<br />

control. From <strong>the</strong> Designer, select Edit Templates from <strong>the</strong> <strong>GridView</strong>'s smart tag and choose <strong>the</strong> HireDate<br />

TemplateField's ItemTemplate from <strong>the</strong> drop­down list. Next, delete <strong>the</strong> Label control and drag a Calendar<br />

control from <strong>the</strong> Toolbox <strong>in</strong>to <strong>the</strong> template edit<strong>in</strong>g <strong>in</strong>terface.


11 of 17<br />

Figure 12: Add a Calendar <strong>Control</strong> to <strong>the</strong> HireDate TemplateField's ItemTemplate<br />

At this po<strong>in</strong>t each row <strong>in</strong> <strong>the</strong> <strong>GridView</strong> will conta<strong>in</strong> a Calendar control <strong>in</strong> its HiredDate TemplateField.<br />

However, <strong>the</strong> employee's actual HiredDate value is not set anywhere <strong>in</strong> <strong>the</strong> Calendar control, caus<strong>in</strong>g each<br />

Calendar control to default to show<strong>in</strong>g <strong>the</strong> current month and date. To remedy this, we need to assign each<br />

employee's HiredDate to <strong>the</strong> Calendar control's SelectedDate and VisibleDate properties.<br />

From <strong>the</strong> Calendar control's smart tag, choose Edit DataB<strong>in</strong>d<strong>in</strong>gs. Next, b<strong>in</strong>d both SelectedDate and<br />

VisibleDate properties to <strong>the</strong> HiredDate data field.<br />

Figure 13: B<strong>in</strong>d <strong>the</strong> SelectedDate and VisibleDate Properties to <strong>the</strong> HiredDate Data Field


12 of 17<br />

Note: The Calendar control's selected date need not necessarily be visible. For example, a Calendar may have<br />

August 1 st , 1999 as <strong>the</strong> selected date, but be show<strong>in</strong>g <strong>the</strong> current month and year. The selected date and<br />

visible date are specified by <strong>the</strong> Calendar control's SelectedDate and VisibleDate properties. S<strong>in</strong>ce we<br />

want to both select <strong>the</strong> employee's HiredDate and make sure that it's shown we need to b<strong>in</strong>d both of <strong>the</strong>se<br />

properties to <strong>the</strong> HireDate data field.<br />

When view<strong>in</strong>g <strong>the</strong> page <strong>in</strong> a browser, <strong>the</strong> calendar now shows <strong>the</strong> month of <strong>the</strong> employee's hired date and<br />

selects that particular date.<br />

Figure 14: The Employee's HiredDate is Shown <strong>in</strong> <strong>the</strong> Calendar <strong>Control</strong><br />

Note: Contrary to all <strong>the</strong> examples we've seen thus far, for this tutorial we did not set EnableViewState<br />

property to false for this <strong>GridView</strong>. The reason for this decision is because click<strong>in</strong>g <strong>the</strong> dates of <strong>the</strong> Calendar<br />

control causes a postback, sett<strong>in</strong>g <strong>the</strong> Calendar's selected date to <strong>the</strong> date just clicked. If <strong>the</strong> <strong>GridView</strong>'s view<br />

state is disabled, however, on each postback <strong>the</strong> <strong>GridView</strong>'s data is rebound to its underly<strong>in</strong>g data source,<br />

which causes <strong>the</strong> Calendar's selected date to be set back to <strong>the</strong> employee's HireDate, overwrit<strong>in</strong>g <strong>the</strong> date<br />

chosen by <strong>the</strong> user.<br />

For this tutorial this is a moot discussion s<strong>in</strong>ce <strong>the</strong> user is not able to update <strong>the</strong> employee's HireDate. It<br />

would probably be best to configure <strong>the</strong> Calendar control so that its dates are not selectable. Regardless, this<br />

tutorial shows that <strong>in</strong> some circumstances view state must be enabled <strong>in</strong> order to provide certa<strong>in</strong> functionality.<br />

Step 4: Show<strong>in</strong>g <strong>the</strong> Number of Days <strong>the</strong> Employee<br />

Has Worked for <strong>the</strong> Company


13 of 17<br />

So far we have seen two applications of <strong>TemplateFields</strong>:<br />

Comb<strong>in</strong><strong>in</strong>g two or more data field values <strong>in</strong>to one column, and<br />

Express<strong>in</strong>g a data field value us<strong>in</strong>g a Web control <strong>in</strong>stead of text<br />

A third use of <strong>TemplateFields</strong> is <strong>in</strong> display<strong>in</strong>g metadata about <strong>the</strong> <strong>GridView</strong>'s underly<strong>in</strong>g data. In addition to<br />

show<strong>in</strong>g <strong>the</strong> employees' hire dates, for example, we might also want to have a column that displays how many<br />

total days <strong>the</strong>y've been on <strong>the</strong> job.<br />

Yet ano<strong>the</strong>r use of <strong>TemplateFields</strong> arises <strong>in</strong> scenarios when <strong>the</strong> underly<strong>in</strong>g data needs to be displayed<br />

differently <strong>in</strong> <strong>the</strong> web page report than <strong>in</strong> <strong>the</strong> format it's stored <strong>in</strong> <strong>the</strong> database. Imag<strong>in</strong>e that <strong>the</strong> Employees<br />

table had a Gender field that stored <strong>the</strong> character M or F to <strong>in</strong>dicate <strong>the</strong> sex of <strong>the</strong> employee. When display<strong>in</strong>g<br />

this <strong>in</strong>formation <strong>in</strong> a web page we might want to show <strong>the</strong> gender as ei<strong>the</strong>r "Male" or "Female", as opposed to<br />

just "M" or "F".<br />

Both of <strong>the</strong>se scenarios can be handled by creat<strong>in</strong>g a formatt<strong>in</strong>g method <strong>in</strong> <strong>the</strong> <strong>ASP</strong>.NET page's code­beh<strong>in</strong>d<br />

class (or <strong>in</strong> a separate class library, implemented as a static method) that is <strong>in</strong>voked from <strong>the</strong> template. Such<br />

a formatt<strong>in</strong>g method is <strong>in</strong>voked from <strong>the</strong> template us<strong>in</strong>g <strong>the</strong> same datab<strong>in</strong>d<strong>in</strong>g syntax seen earlier. The<br />

formatt<strong>in</strong>g method can take <strong>in</strong> any number of parameters, but must return a str<strong>in</strong>g. This returned str<strong>in</strong>g is <strong>the</strong><br />

HTML that is <strong>in</strong>jected <strong>in</strong>to <strong>the</strong> template.<br />

To illustrate this concept, let's augment our tutorial to show a column that lists <strong>the</strong> total number of days an<br />

employee has been on <strong>the</strong> job. This formatt<strong>in</strong>g method will take <strong>in</strong> a Northw<strong>in</strong>d.EmployeesRow object and<br />

return <strong>the</strong> number of days <strong>the</strong> employee has been employed as a str<strong>in</strong>g. This method can be added to <strong>the</strong><br />

<strong>ASP</strong>.NET page's code­beh<strong>in</strong>d class, but must be marked as protected or public <strong>in</strong> order to be accessible<br />

from <strong>the</strong> template.<br />

protected str<strong>in</strong>g DisplayDaysOnJob(Northw<strong>in</strong>d.EmployeesRow employee)<br />

{<br />

// Make sure HiredDate is not null... if so, return "Unknown"<br />

if (employee.IsHireDateNull())<br />

return "Unknown";<br />

else<br />

{<br />

// Returns <strong>the</strong> number of days between <strong>the</strong> current<br />

// date/time and HireDate<br />

TimeSpan ts = DateTime.Now.Subtract(employee.HireDate);<br />

return ts.Days.ToStr<strong>in</strong>g("#,##0");<br />

}<br />

}<br />

S<strong>in</strong>ce <strong>the</strong> HiredDate field can conta<strong>in</strong> NULL database values we must first ensure that <strong>the</strong> value is not NULL<br />

before proceed<strong>in</strong>g with <strong>the</strong> calculation. If <strong>the</strong> HiredDate value is NULL, we simply return <strong>the</strong> str<strong>in</strong>g<br />

"Unknown"; if it is not NULL, we compute <strong>the</strong> difference between <strong>the</strong> current time and <strong>the</strong> HiredDate value<br />

and return <strong>the</strong> number of days.<br />

To utilize this method we need to <strong>in</strong>voke it from a TemplateField <strong>in</strong> <strong>the</strong> <strong>GridView</strong> us<strong>in</strong>g <strong>the</strong> datab<strong>in</strong>d<strong>in</strong>g<br />

syntax. Start by add<strong>in</strong>g a new TemplateField to <strong>the</strong> <strong>GridView</strong> by click<strong>in</strong>g on <strong>the</strong> Edit Columns l<strong>in</strong>k <strong>in</strong> <strong>the</strong><br />

<strong>GridView</strong>'s smart tag and add<strong>in</strong>g a new TemplateField.


14 of 17<br />

Figure 15: Add a New TemplateField to <strong>the</strong> <strong>GridView</strong><br />

Set this new TemplateField's HeaderText property to "Days on <strong>the</strong> Job" and its ItemStyle's<br />

HorizontalAlign property to Center. To call <strong>the</strong> DisplayDaysOnJob method from <strong>the</strong> template, add an<br />

ItemTemplate and use <strong>the</strong> follow<strong>in</strong>g datab<strong>in</strong>d<strong>in</strong>g syntax:<br />

<br />

Conta<strong>in</strong>er.DataItem returns a DataRowView object correspond<strong>in</strong>g to <strong>the</strong> DataSource record bound to <strong>the</strong><br />

<strong>GridView</strong>Row. Its Row property returns <strong>the</strong> strongly­typed Northw<strong>in</strong>d.EmployeesRow, which is passed to <strong>the</strong><br />

DisplayDaysOnJob method. This datab<strong>in</strong>d<strong>in</strong>g syntax can appear directly <strong>in</strong> <strong>the</strong> ItemTemplate (as shown <strong>in</strong><br />

<strong>the</strong> declarative syntax below) or can be assigned to <strong>the</strong> Text property of a Label Web control.<br />

Note: Alternatively, <strong>in</strong>stead of pass<strong>in</strong>g <strong>in</strong> an EmployeesRow <strong>in</strong>stance, we could just pass <strong>in</strong> <strong>the</strong> HireDate value<br />

us<strong>in</strong>g . However, <strong>the</strong> Eval method returns an object, so<br />

we'd have to change our DisplayDaysOnJob method signature to accept an <strong>in</strong>put parameter of type object,<br />

<strong>in</strong>stead. We can't bl<strong>in</strong>dly cast <strong>the</strong> Eval("HireDate") call to a DateTime because <strong>the</strong> HireDate column <strong>in</strong> <strong>the</strong><br />

Employees table can conta<strong>in</strong> NULL values. Therefore, we'd need to accept an object as <strong>the</strong> <strong>in</strong>put parameter<br />

for <strong>the</strong> DisplayDaysOnJob method, check to see if it had a database NULL value (which can be accomplished<br />

us<strong>in</strong>g Convert.IsDBNull(objectToCheck)), and <strong>the</strong>n proceed accord<strong>in</strong>gly.<br />

Due to <strong>the</strong>se subtleties, I've opted to pass <strong>in</strong> <strong>the</strong> entire EmployeesRow <strong>in</strong>stance. In <strong>the</strong> next tutorial we'll see a<br />

more fitt<strong>in</strong>g example for us<strong>in</strong>g <strong>the</strong> Eval("columnName") syntax for pass<strong>in</strong>g an <strong>in</strong>put parameter <strong>in</strong>to a<br />

formatt<strong>in</strong>g method.<br />

The follow<strong>in</strong>g shows <strong>the</strong> declarative syntax for our <strong>GridView</strong> after <strong>the</strong> TemplateField has been added and <strong>the</strong><br />

DisplayDaysOnJob method called from <strong>the</strong> ItemTemplate:<br />


15 of 17<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Figure 16 shows <strong>the</strong> completed tutorial, when viewed through a browser.


16 of 17<br />

Figure 16: The Number of Days <strong>the</strong> Employee Has Been on <strong>the</strong> Job is Displayed<br />

Summary<br />

The TemplateField <strong>in</strong> <strong>the</strong> <strong>GridView</strong> control allows for a higher degree of flexibility <strong>in</strong> display<strong>in</strong>g data than is<br />

available with <strong>the</strong> o<strong>the</strong>r field controls. <strong>TemplateFields</strong> are ideal for situations where:<br />

Multiple data fields need to be displayed <strong>in</strong> one <strong>GridView</strong> column<br />

The data is best expressed us<strong>in</strong>g a Web control ra<strong>the</strong>r than pla<strong>in</strong> text<br />

The output depends on <strong>the</strong> underly<strong>in</strong>g data, such as display<strong>in</strong>g metadata or <strong>in</strong> reformatt<strong>in</strong>g <strong>the</strong> data<br />

In addition to customiz<strong>in</strong>g <strong>the</strong> display of data, <strong>TemplateFields</strong> are also used for customiz<strong>in</strong>g <strong>the</strong> user <strong>in</strong>terfaces<br />

used for edit<strong>in</strong>g and <strong>in</strong>sert<strong>in</strong>g data, as we'll see <strong>in</strong> future tutorials.<br />

The next two tutorials cont<strong>in</strong>ue explor<strong>in</strong>g templates, start<strong>in</strong>g with a look at us<strong>in</strong>g <strong>TemplateFields</strong> <strong>in</strong> a<br />

DetailsView. Follow<strong>in</strong>g that, we'll turn to <strong>the</strong> FormView, which uses templates <strong>in</strong> lieu of fields to provide<br />

greater flexibility <strong>in</strong> <strong>the</strong> layout and structure of <strong>the</strong> data.<br />

Happy Programm<strong>in</strong>g!<br />

Click here for <strong>the</strong> next tutorial<br />

About <strong>the</strong> Author<br />

Scott Mitchell, author of six <strong>ASP</strong>/<strong>ASP</strong>.NET books and founder of 4GuysFromRolla.com, has been work<strong>in</strong>g


17 of 17<br />

with Microsoft Web technologies s<strong>in</strong>ce 1998. Scott works as an <strong>in</strong>dependent consultant, tra<strong>in</strong>er, and writer,<br />

recently complet<strong>in</strong>g his latest book, Sams Teach Yourself <strong>ASP</strong>.NET 2.0 <strong>in</strong> 24 Hours. He can be reached at<br />

mitchell@4guysfromrolla.com or via his blog, which can be found at http://ScottOnWrit<strong>in</strong>g.NET.<br />

Special Thanks To…<br />

This tutorial series was reviewed by many helpful reviewers. Lead reviewer for this tutorial was Dan Jagers.<br />

Interested <strong>in</strong> review<strong>in</strong>g my upcom<strong>in</strong>g MSDN articles? If so, drop me a l<strong>in</strong>e at mitchell@4GuysFromRolla.com.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!