让我们增加一点内容来说明这个概念。主要是增加一列以显示雇员在公司干活的天数。这个格式化方法接受一个Northwind.EmployeesRow对象,然后返回以字符串的形式返回这个雇员在公司干活的天数。这个方法可以添加到ASP.NET页面的后置代码类中,不过一定要记得将其标记为protected或public,不然模板就访问不到它了。
protected string DisplayDaysOnJob(Northwind.EmployeesRow employee) { // Make sure HiredDate is not null... if so, return "Unknown" if (employee.IsHireDateNull()) return "Unknown"; else { // Returns the number of days between the current // date/time and HireDate TimeSpan ts = DateTime.Now.Subtract(employee.HireDate); return ts.Days.ToString("#,##0"); } }
由于HiredDate可能会含有空值,所以我们必须在进行计算之前首先保证其值不为空。如果HiredDate值为空的话,直接返回一个“Unknown”就是了;如果不为空的话呢,就计算当前时间跟HiredDate的值之间所隔的天数,并把它作为一个字符串返回即可。
要使用这个方法,我们需要在GridView的TemplateField中使用数据绑定语法来调用它。同样,我们还是先给GridView添加一个新的模板列。
图十五:给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 runat="server" AutoGenerateColumns="False" DataKeyNames="EmployeeID" DataSourceID="ObjectDataSource1"> <Columns> <asp:TemplateField HeaderText="Name" SortExpression="FirstName"> <EditItemTemplate> <asp:TextBox runat="server" Text='<%# Bind("FirstName") %>'></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:Label runat="server" Text='<%# Bind("FirstName") %>'></asp:Label> <asp:Label 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 runat="server" Text='<%# Bind("HireDate") %>'></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:Calendar 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>
完成了整节教程之后,页面在浏览器中的样子应该是图十六的这个样子。
图十六:“雇员在公司干了多久“也显示出来了
总结
在GridView控件中,相对于其他的列控件来说,模板列可以处理更加复杂的数据呈现。模板列主要用于这样一些情况:
·一个GridView列中需要显示多个数据列
·使用一个Web控件来展示数据比一段简单的文本更好
·页面的输出取决于绑定到GridView的数据,比如说元数据或者说是数据的重新格式化
除了自定义数据的显示,模板列也用于编辑和插入数据时的用户界面的自定义,这个我们在后面的章节中将会讲到。