Scott Mitchell 的ASP.NET 2.0数据教程之十三:在DetailsView控件中使用TemplateField

在ASP.NET 2.0中操作数据:在DetailsView控件中使用TemplateField

英文原版

导言

 
·         在一列中显示多个数据字段。比如说,将FirstName和LastName字段合并起来显示在一个GridView列中。
·         使用交互Web控件来展示数据。我们看到了如何使用一个Calendar控件来显示HiredDate的值。
·         显示基于潜在数据的状态信息。尽管Employees表中并没有包含一个关于雇员在公司干了多久的数据列,但我们仍然可以使用TemplateField 和格式化方法在GridView中实现这样的功能,就像我们在上一节中做的那样。
 
就像在GridView中那样,DetailsView控件也可以同样的使用TemplateField。在本节教程中,我们将使用一个包含两个TemplateField的DetailsView来一次一个的显示产品信息。第一个TemplateField将整合UnitPrice、UnitsInStock和UnitsOnOrder等数据并显示在一个DetailsView行上。第一个TemplateField则将显示Discontinued的数据,不过将使用格式化方法,在有折扣的时候就显示“YES”,否则就显示“NO”。




图九:字符串“True”和“False”用来显示打折状态
图一:使用两个模板列来自定义显示

好了,让我们开始吧!
 
第一步:将数据绑定到DetailsView 

像前一节中所讨论的那样,要使用TemplateField最简单的办法就是先创建一个仅包含BoundField的DetailsView控件,然后添加新的TemplateField或是将某些BoundField转换成TemplateField。因此,我们先通过设计器向页面上添加一个DetailsView控件,并绑定一个返回产品列表的ObjectDataSource给它。这些操作将创建一个带有BoundField和CheckBoxField 的DetailsView,BoundField用于非布尔值,CheckBoxField当然就是用于布尔值了(比如说“是否打折”)。
 
打开DetailsViewTemplateField.aspx 页面,从工具箱中拖一个DetailsView到设计器上。从DetailsView的智能标签(smart tag)上选择并添加一个新的调用ProductsBLL类的GetProducts () 方法的ObjectDataSource控件。


图二:添加一个新的调用GetProducts () 方法的ObjectDataSource控件

在这个报表中,删除ProductID 、SupplierID 、CategoryID 以及ReorderLevel 等BoundField。然后,调整剩下的BoundField的顺序以使CategoryName 和SupplierName 跟在 ProductName 后面。然后设置各BoundField的HeaderText 和formatting属性,不用紧张,随便填,只要你觉得爽就行。就像在GridView中那样,可以通过字段对话框或是直接修改声明代码(declarative syntax。译者注:直译应该是什么?声明语法?不管怎么样,反正就是HTML视图里面的那些东西)来编辑这些绑定列。最后,清空DetailsView的Height和Width属性,这样可以使其根据需要显示的数据来自动扩展,另外,再在智能标签中选上“启用分页(Enable Paging)”复选框。
 
在做了这些更改之后,你的DetailsView控件的声明标记应该像下面这样:
 
 1 < asp:DetailsView  ID ="DetailsView1"  runat ="server"  AutoGenerateRows ="False"  DataKeyNames ="ProductID"
 2     DataSourceID ="ObjectDataSource1"  AllowPaging ="True"  EnableViewState ="False" >
 3      < Fields >
 4          < asp:BoundField  DataField ="ProductName"  HeaderText ="Product"  SortExpression ="ProductName"  />
 5          < asp:BoundField  DataField ="CategoryName"  HeaderText ="Category"  ReadOnly ="True"  SortExpression ="CategoryName"  />
 6          < asp:BoundField  DataField ="SupplierName"  HeaderText ="Supplier"  ReadOnly ="True"  SortExpression ="SupplierName"  />
 7          < asp:BoundField  DataField ="QuantityPerUnit"  HeaderText ="Qty/Unit"  SortExpression ="QuantityPerUnit"  />
 8          < asp:BoundField  DataField ="UnitPrice"  HeaderText ="Price"  SortExpression ="UnitPrice"  />
 9          < asp:BoundField  DataField ="UnitsInStock"  HeaderText ="Units In Stock"  SortExpression ="UnitsInStock"  />
10          < asp:BoundField  DataField ="UnitsOnOrder"  HeaderText ="Units On Order"  SortExpression ="UnitsOnOrder"  />
11          < asp:CheckBoxField  DataField ="Discontinued"  HeaderText ="Discontinued"  SortExpression ="Discontinued"  />
12      </ Fields >
13 </ asp:DetailsView >
14

同样,我们还是花点时间到浏览器中看看效果吧!现在,你可以看到一个单独的产品(Chai),它包括一些显示其属性的行:名称、分类、供应商、库存量、订货量还有它的打折状态。


图三:使用一组绑定列来显示产品明细
 
第二步:将单价、库存量和订货量合并在一列中

DetailsView有一列用于UnitPrice、UnitsInStock和UnitsOnOrder。通过TemplateField可以将这3个数据合并到一行中,你可以添加一个新的TemplateField,也可以将UnitPrice、UnitsInStock或UnitsOnOrder任何一个BoundField直接转换成TemplateField。虽然我个人还是喜欢将已有的BoundField转换成TemplateField这种方式,不过这里我们还是来联系一下添加新的TemplateField吧。
 
在DetailsView的智能标签的弹出菜单中点击“编辑字段(Edit Fields)”。在弹出的字段对话框中,添加一个新的TemplateField并将其HeaderText属性设置为“Price and Inventory”,然后将这个新的TemplateField移动到UnitPrice的上面。


图四:给DetailsView控件添加一个模板列
 
由于新添加的TemplateField将要显示UnitPrice、UnitsInStock以及UnitsOnOrder 等BoundField中的数据,所以让我们先把这几个BoundField删了。
 
这一个步骤的最后一个任务是定义“Price and Inventory”这个TemplateField 的ItemTemplate,你可以通过设计器中DetailsView的模板编辑界面也可以手工编写声明代码来完成这个任务。就像GridView那样,在智能标签的弹出菜单中点击“编辑模板”( Edit Templates),就可以使用模板编辑界面了。这里你可以在下拉框中选择你想要编辑的模板并从工具箱中添加任何你喜欢的Web控件。
 
在本教程中,首先给“Price and Inventory”模板列的ItemTemplate添加一个Label。然后,在Label控件的智能标签上点击“编辑数据绑定(Edit DataBindings)”并将其Text属性绑定到UnitPrice字段上。


图五:将Label的Text属性绑定到UnitPrice字段上

将单价格式化为货币形式

做了这个操作之后,“Price and Inventory”模板列的Label上仅显示了所选产品的单价。图六向我们展示了到现在为止我们所做的成果。


图六:“单价和总量”模板列显示了单价
 
注意产品的单价现在还没有格式化为货币格式。如果是一个BoundField,格式化可以通过将HtmlEncode属性设置为false并将DataFormatString属性设置为“{0:formatSpecifier}”来实现。然而,在TemplateField中,任何格式化说明都必须在数据绑定语法中指定或是通过使用一个在应用程序的某个地方(比如说在ASP.NET页面的后置代码类中)编写的格式化方法。
 
要指定Label的数据绑定代码中的格式化,可以在Label的智能标签中点击“编辑数据绑定(Edit DataBindings)”,然后在弹出的数据绑定对话框中的格式(Format)下拉框直接输入格式化说明或选择一个预定义的格式化字符串。就像BoundField的DataFormatString属性那样,格式化使用{0:formatSpecifier} 来进行指定。
 
为了使UnitPrice字段使用货币格式,我们可以在那个下拉框中选择一个合适值,也可以直接输入“{0:C}”。


图七:将单价格式化为货币形式
 
说明一下,格式化说明是Bind或Eval方法的第二个参数。刚才通过设计器添加的这个设置表现为以下的标记语言:
 
< asp:Label  ID ="Label1"  runat ="server"  Text ='<%#  Eval("UnitPrice", "{0:C}") % > '> </ asp:Label >
 
将剩下的数据字段添加到TemplateField中

现在,我们已经在“Price and Inventory”模板列中显示并格式化了UnitPrice字段,不过我还需要将UnitsInStock 和UnitsOnOrder 显示出来。让我们把它们显示在单价的下面一行的圆括号中吧!在设计器的模板编辑器中,这些用于显示的标记语言可以简单的用键盘输入,当然你需要先将光标定位到模板中的某个位置。另外,你也可以直接在声明代码中直接输入。
 
添加了静态的标记语言、Label控件以及数据绑定代码,所以“Price and Inventory”模板列可以像下面这样显示单价和总量信息:
 
单价
(In Stock / On Order: 库存量/订货量)
 
做了这些之后,你的DetailsView的声明标记代码应该像这个样子:

 1 < asp:DetailsView  ID ="DetailsView1"  runat ="server"  AutoGenerateRows ="False"  DataKeyNames ="ProductID"
 2     DataSourceID ="ObjectDataSource1"  AllowPaging ="True"  EnableViewState ="False" >
 3      < Fields >
 4          < asp:BoundField  DataField ="ProductName"  HeaderText ="Product"  SortExpression ="ProductName"  />
 5          < asp:BoundField  DataField ="CategoryName"  HeaderText ="Category"  ReadOnly ="True"  SortExpression ="CategoryName"  />
 6          < asp:BoundField  DataField ="SupplierName"  HeaderText ="Supplier"  ReadOnly ="True"  SortExpression ="SupplierName"  />
 7          < asp:BoundField  DataField ="QuantityPerUnit"  HeaderText ="Qty/Unit"  SortExpression ="QuantityPerUnit"  />
 8          < asp:TemplateField  HeaderText ="Price and Inventory" >
 9              < ItemTemplate >
10                  < asp:Label  ID ="Label1"  runat ="server"  Text ='<%#  Eval("UnitPrice", "{0:C}") % > '> </ asp:Label >
11                  < br  />
12                  < strong >
13                 (In Stock / On Order:  </ strong >
14                  < asp:Label  ID ="Label2"  runat ="server"  Text ='<%#  Eval("UnitsInStock") % > '> </ asp:Label >
15                  < strong > / </ strong >
16                  < asp:Label  ID ="Label3"  runat ="server"  Text ='<%#  Eval("UnitsOnOrder") % > '> </ asp:Label >< strong > ) </ strong >
17              </ ItemTemplate >
18          </ asp:TemplateField >
19          < asp:CheckBoxField  DataField ="Discontinued"  HeaderText ="Discontinued"  SortExpression ="Discontinued"  />
20      </ Fields >
21 </ asp:DetailsView >
22
 
做了这些修改之后,我们已经把单价和总量信息统一的显示在一个单独的DetailsView行中了。

图八:单价和总量信息显示在一个单独的行上了
 
第三步:自定义折扣字段的信息
Products表的Discontinued字段是一个BIT值,它指明一个产品是否打折。当把一个DetailsView(或者GridView)绑定到一个数据源控件时,布尔型的字段(比如说Discontinued)会被实现为CheckBoxField,而非布尔型的字段(比如说ProductID、ProductName等等)将被实现为BoundField。CheckBoxField被呈现为一个禁用的CheckBox,如果数据的值为true则CheckBox为选中状态,否则就是未选中状态。
 
比起显示一个CheckBoxField,可能我们更希望将其显示为一个文本以说明这个产品是不是有折打。要做到这一点,我们可以从DetailsView中删掉这个CheckBoxField,再添加一个BoundField,并将其DataField属性设置到Discontinued上。嗯,花点时间完成它!做完这个改变后,DetailsView对那些打折的产品就显示一个“True”,而对其他的就显示一个“False”。
 
想想一下,我们不想用“True”或者“False”,而是想要“YES”和“NO”。这样的自定义可以由一个TemplateField和一个格式化方法来实现。格式化方法可以接受若干个输入参数,但是智能返回一个用于插入到模板中的HTML(字符串类型的)
 
在DetailsViewTemplateField.aspx页面的后置代码类中添加一个名为DisplayDiscontinuedAsYESorNO的格式化方法,它接受一个布尔型的值作为参数并返回一个字符串。就像前一节中讨论的那样,这个方法必须标记为protected或是public,不然就不能从模板中访问到它了。
 
1 protected  string  DisplayDiscontinuedAsYESorNO( bool  discontinued)
2 {
3    if (discontinued)
4        return "YES";
5    else
6        return "NO";
7}

8

这个方法检查输入的参数(是否折扣),如果为true则返回“YES”,否则就返回“NO”。
 
注意:回忆一下我们在上一节中的相关内容,传递给格式化方法的参数可能是空值,所以我们需要在访问雇员的HiredDate之前对它进行空值检查。这样的检查在这里却是不需要的,因为Discontinued字段永远不会是空值。此外,这也是为什么这个方法接受的是一个布尔值而不是ProductsRow实例或object类型的参数的原因。
 
完成了这个格式化方法之后,剩下的就只是在TemplateField的ItemTemplate中调用它了。要创建这个TemplateField,我们可以删除Discontinued绑定列再添加一个新的TemplateField,也可以直接将Discontinued BoundField转换成TemplateField。然后,在源视图(译者注:就是HTML视图)编辑TemplateField以使其包含一个调用DisplayDiscontinuedAsYESorNO方法的ItemTemplate,传过去的参数就是当前ProductRow实例的Discontinued属性。这个可以通过Eval方法来访问。现在,这个TemplateField的标记代码就像这样了:
 
1 < asp:TemplateField  HeaderText ="Discontinued"  SortExpression ="Discontinued" >
2      < ItemTemplate >
3          <% # DisplayDiscontinuedAsYESorNO((bool) Eval("Discontinued"))  %>
4      </ ItemTemplate >
5 </ asp:TemplateField >
6

这样,DisplayDiscontinuedAsYESorNO方法就会在呈现DetailsView时被调用,传给它的是ProductRow实例的Discontinued值。由于Eval方法返回的是一个obejct类型的值,而DisplayDiscontinuedAsYESorNO方法仅接受布尔型的参数,所以我们将Eval方法的返回值转换成布尔型的。根据接收到的值,DisplayDiscontinuedAsYESorNO方法将会返回“YES”或“NO”,这个返回值就是要在这个DetailsView行中显示的东西。


图十:现在在折扣行中显示的就是“YES”或“NO”了
 
总结

在DetailsView控件中,相对于其他的列控件来说,模板列可以处理更加复杂的数据呈现。模板列主要用于这样一些情况:
 
·         一个DetailsView列中需要显示多个数据列
·         使用一个Web控件来展示数据比一段简单的文本更好
·         页面的输出取决于绑定到DetailsView的数据,比如说元数据或者说是数据的重新格式化
 
虽然模板列可以高度复杂的呈现DetailsView的数据,但DetailsView的输入仍然让人感到有些别扭,因为它把每个字段都显示成HTML标记<table>的一行。
 
FormView控件提供了一种更加复杂的输出呈现。FormView并不含有什么列,它仅仅包括一系列的模板(ItemTemplate、EditItemTemplate、HeaderTemplate等等)。在下一节中,我们将看到如何使用FormView来达到呈现更多控件的效果。
 
编程愉快
  |    本教程的代码(C#)   |   翻译目录   |   原文目录
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值