第三种TemplateField的用法是,显示GridView中数据的元数据。比如说,除了显示雇员的受雇日期,我们可能还希望用一列来显示这个雇员在公司干了多久。
另外还有一种用法,它将在某些情况下需要用到,比如说在页面上某个数据的显示格式需要用一种不同于其在数据库中的存储格式的时候。想象一下,雇员表中有一个性别字段,其中存储了M或是F这样的字符用于表示此雇员是男的还是女的。当我们需要将这个信息显示在页面上的时候,我们可能希望能够将其显示为“男”或“女”而不是“M”或“F”。
这两种用法都可以采用在ASP.NET页面的后置代码类(或者是在一个独立的类库中,将其实现为一个静态方法)创建一个供模板调用的格式化方法(formatting method)来做到。这样的格式化方法将在模板中调用,语法跟前面的数据绑定语法是一样的。格式化方法可以接受若干个参数,但是必须返回一个字符串。这个返回的字符串是一个用于插入到模板中的HTML。
让我们增加一点内容来说明这个概念。主要是增加一列以显示雇员在公司干活的天数。这个格式化方法接受一个Northwind.EmployeesRow对象,然后返回以字符串的形式返回这个雇员在公司干活的天数。这个方法可以添加到ASP.NET页面的后置代码类中,不过一定要记得将其标记为protected或public,不然模板就访问不到它了。
- protected string DisplayDaysOnJob(Northwind.EmployeesRow employee)
- {
- // 确保HiredDate不为空……如果为空的话,返回“Unknown”
- if (employee.IsHireDateNull())
- return "Unknown";
- else
- {
- // 返回当前日期/时间与HireDate之间所隔的天数
- TimeSpan ts = DateTime.Now.Subtract(employee.HireDate);
- return ts.Days.ToString("#,##0");
- }
由于HiredDate可能会含有空值,所以我们必须在进行计算之前首先保证其值不为空。如果HiredDate值为空的话,直接返回一个“Unknown”就是了;如果不为空的话呢,就计算当前时间跟HiredDate的值之间所隔的天数,并把它作为一个字符串返回即可。
要使用这个方法,我们需要在GridView的TemplateField中使用数据绑定语法来调用它。同样,我们还是先给GridView添加一个新的模板列。
TemplateField:给GridView添加一个新的模板列
将这个新的模板列的页眉文本(HeaderText)设置成“Days on the Job”,并将其ItemStyle的水平对齐(HorizontalAlign)设置为居中(Center)。要调用DisplayDaysOnJob方法,我们需要给这个模板列添加一个ItemTemplate并加上如下的数据绑定代码:
- < %# DisplayDaysOnJob((Northwind.EmployeesRow) ((System.Data.DataRowView) Container.DataItem).Row) %>
Container.DataItem返回数据源对象中的一个相应的DataRowView对象给GridView。它的Row属性返回一个强类型化的Nothwind.EmployeesRow,然后再将其传递给DisplayDaysOnJob方法。这个数据绑定语法可以直接出现再ItemTemplate(就像下面的代码中那样)中或是赋值给Label控件的Text属性。
注意:除了传递一个EmployeesRow的实例,其实我们也可以仅仅传递HireDate的值,使用< %# DisplayDaysOnJob(Eval("HireDate")) %>就可以了。不过呢,Eval方法将返回一个object类型,所以我们就必须要修改DisplayDaysOnJob方法的签名以使其可以接受一个object类型的参数。我们不能将Eval("HireDate")调用的结果隐式的转换成一个DateTime类型,因为Employees表的HireDate字段是允许为空的。因此,我们需要使DisplayDaysOnJob方法可以接受一个object类型的参数,并判断这个参数是不是空值(我们可以使用Convert.IsDBNull(objectToCheck)来完成这个验证工作),然后再进行后面的操作。
就是因为这个,所以我还是选择了传递整个EmployeesRow实例。在下一节教程中,我们会看到一个更加合适使用Eval("columnName")来传递参数给格式化方法的例子。
在给我们的GridView添加了模板列并在ItemTemplate中添加了调用DisplayDaysOnJob方法的代码后,声明代码应该是这个样子:
- < asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
- DataKeyNames="EmployeeID"
- DataSourceID="ObjectDataSource1">
- < Columns>
- < asp:TemplateField HeaderText="Name" SortExpression="FirstName">
- < EditItemTemplate>
- < asp:TextBox ID="TextBox1" runat="server" Text='< %# Bind("FirstName") %>'>
- < /asp:TextBox>
- < /EditItemTemplate>
- < ItemTemplate>
- < asp:Label ID="Label1" runat="server" Text='< %# Bind("FirstName") %>'>< /asp:Label>
- < asp:Label ID="Label2" runat="server" Text='< %# Eval("LastName") %>'>< /asp:Label>
- < /ItemTemplate>
- < /asp:TemplateField>
- < asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
- < asp:TemplateField HeaderText="HireDate" SortExpression="HireDate">
- < EditItemTemplate>
- < asp:TextBox ID="TextBox2" runat="server" Text='< %# Bind("HireDate") %>'>
- < /asp:TextBox>
- < /EditItemTemplate>
- < ItemTemplate>
- < asp:Calendar ID="Calendar1" runat="server" SelectedDate='< %# Bind("HireDate") %>'
- VisibleDate='< %# Eval("HireDate") %>'>< /asp:Calendar>
- < /ItemTemplate>
- < /asp:TemplateField>
- < asp:TemplateField HeaderText="Days On The Job">
- < ItemTemplate>
- < %# DisplayDaysOnJob((Northwind.EmployeesRow) ((System.Data.DataRowView)
- Container.DataItem).Row) %>
- < /ItemTemplate>
- < ItemStyle HorizontalAlign="Center" />
- < /asp:TemplateField>
- < /Columns>
- < /asp:GridView>
完成了整节教程之后,页面在浏览器中的样子应该是图十六的这个样子。
TemplateField:“雇员在公司干了多久”也显示出来了
【编辑推荐】