尽管有丰富功能强大的编程接口ASPNET x DataGrid 控件仍需要编写大量自定义代码来处理普通操作如分页排序编辑和删除数据例如当用户单击以保存或取消更改时DataGrid 控件能够引发事件但不提供更多的功能如果要将更改存储到持续媒介(如一个数据库)之中则必须自己处理 UpdateCommand 事件检索更改后的值编写一条 SQL 命令然后从该处提交更新
DataGrid 控件限制普通数据操作的引发事件因为它是一个数据源不可知的控件能够绑定到任何可枚举的数据对象执行数据操作(如更新或删除)需要直接连接到一个特定的数据源在 ASPNET x 中则通过编写特定于应用程序的 ADONET 代码解决这个问题的
ASPNET 改进了数据绑定体系结构引入了新的系列组件(数据源对象)作为数据绑定控件与 ADONET 对象之间的桥梁这些源对象提升了一个略为不同的编程模型提供了新功能和新成员您的 ASPNET 应用程序应该使用最新的网格控件 — GridView显示数据报告与之相似的 DataGrid 控件仍然支持但 DataGrid 不能充分利用数据源组件的特定功能
GridView 控件是 DataGrid 的接替者并从几个方面扩展了后者的功能首先它完全支持数据源组件能够自动处理诸如分页排序和编辑等数据操作前提是绑定的数据源对象支持这些操作另外GridView 控件有一些比 DataGrid 优越的功能上的改进特别是它支持多个主键字段公开了一些用户界面的改进功能和一个处理与取消事件的新模型
GridView 附带了一对互补的视图控件DetailsView 和 FormView通过这些控件的组合您能够轻松地建立主/详细视图而只需少量代码有时根本不需要代码
GridView 与 DataGrid
ASPNET 中数据绑定控件的类层次结构比 ASPNET x 中的更一致在 版本中所有控件无论有什么样的实际实现过程和用户界面特点均从同一个基类(BaseDataBoundControl 类)派生图 显示新的类关系图DataGrid 和其他 x 版本的控件(如 Repeater 和 DataList)没有包含在该关系图中这些现有控件的继承树与 ASPNET x 的相同特别是Repeater 继承了 WebControl而 DataList 和 DataGrid 继承了 BaseDataList如图 所示GridView 是一个复合数据绑定控件它与其他所有数据绑定控件(包括 DropDownListDetailsView 和 ListBox)共享一组方法和属性
GridView 和 DataGrid 控件的高级功能相似但基础却不同GridView 尽可能地保留了 DataGrid 的对象模型以便轻松地从现有页面进行移植但是基于 DataGrid 的代码与新的基于 GridView 的代码不可能 % 兼容
DataGrid 与 GridView 控件的另一个主要差异在于自适应用户界面与 x 版本的 DataGrid 不同的是GridView 也能在移动设备上显示换句话说您能够使用相同的用于桌面页面的网格控件在移动设备上生成报告 版本的 DataGrid 也能自适应地显示但是它的 UI 功能没有 GridView 丰富
在 ASPNET 中改进后的 DataGrid 控件支持诸如主题和个性化等通用的控件功能此外新的 DataGrid 控件可由一个数据源控件填充但要记住绑定到数据源对象的 DataGrid 只能用于读取数据要实际修改底层数据源仍然需要一些用户定义的代码而 GridView 控件可以利用底层数据源的功能并自动删除或更新记录注意GridView 控件也支持传统的基于 DataSource 属性和 DataBind 方法的绑定机制尽管完全支持这种绑定机制但是不鼓励使用这样的编程实践方法
GridView 和数据源控件
那么数据源控件是什么?我在 年 月一期的 MSDN?Magazine 中详细介绍了 ASPNET 的这项流行的新功能简言之一个数据源控件就是一组 Microsoft? NET Framework 类它有利于数据存储和数据绑定控件之间的双向绑定现有的控件(如 DataGrid)以及新的数据绑定控件(如 GridView)尽管绑定能力不同但都能绑定到一个数据源
一个数据源控件代表了数据源的主要功能选择插入更新和删除数据源控件能代表任何数据源从关系数据源库到 XML 文件从流数据到业务对象如果简要介绍能让您想起 NET 的托管提供程序请参见图
图数据源控件GridView和数据源
数据源控件可以位于一些 NET 数据提供程序的上层在数据绑定控件和数据源之间形成一个中间层数据源控件也会公开一个提供基本操作的公共接口一些数据绑定控件 — 特别是 GridView 控件将这些命令与其他与数据有关的操作一起绑定到适当的自动编辑
数据源控件通过其属性和方法将绑定内容以一组命名的视图形式公开IDataSource 接口提供从数据源检索数据视图的基本功能集所有数据源控件都实现了这个接口ASPNET 提供一些内置数据源控件如图 所列图 列出的数据源控件属于两类列表和分层组件SiteMapDataSource 和 XmlDataSource 组件是分层数据源控件用于像 TreeView 和 Menu 控件这样的分层组件其他各种组件用于管理列表数据
图 中的代码说明如何在一个示例页面上将 GridView 和 DataGrid 绑定到同一个数据源控件在 ASPNET 中这是推荐的数据绑定方法SqlDataSource 控件的特点是一个 ConnectionString 属性加上 SelectCommandUpdateCommandInsertCommand 和 DeleteCommand 属性的任意组合所有属性都是字符串形式并且引用带有可选参数的命令文本
<asp:SqlDataSourcerunat=
server
ID=MySource
ConnectionString=SERVER=(local);
DATABASE=northwind;IntegratedSecurity=SSPI;
SelectCommand=SELECT*FROMemployeesWHEREemployeeid>@MinID>
<SelectParameters>
<asp:ControlParameterName=MinID
ControlId=EmpID
PropertyName=Text/>
</SelectParameters>
</asp:SqlDataSource>
每个数据源控件由唯一的 ID 表示ID 是连结数据绑定控件和数据源控件之间的纽带通过 DataSourceId 属性将 GridView 绑定到一个数据源控件例如每当网格需要获取数据时就执行与 SQLDataSource 控件相关联的 SelectCommand SQL 命令当网格需要更新或删除一条记录时就执行相应的 UpdateCommand 或 DeleteCommand SQL 命令如果不存在这样的命令则引发一个异常在内部当用户删除或更新一条记录时GridView 就像 x 版本的 DataGrid 一样引发事件但是与 DataGrid 不同的是GridView 为这些事件定义内部的处理程序默认的处理程序检索绑定数据源定义的命令来处理和执行这些操作图 说明在保持网格显示或更新数据的标记后无需编写代码在更复杂的情况下您可能需要编写一些代码
图 GridView 和 DataGrid
数据源控件和 GridView 控件通常用于无代码数据绑定图 显示图 的代码生成的输出结果
在 ASPNET 中除了 DataSource 和 DataMemberDataGrid 还公开了 DataSourceId 属性DataSourceId 属性将 DataGrid 连接到同一页面上定义的一个合法数据源对象但是DataGrid 不提供与 GridView 同一级别的自动化操作当用户单击以更新一条记录时DataGrid 引发 UpdateCommand 事件而 GridView 除了引发 Updating 和 Updated 事件外还检索和执行数据源更新命令允许用户自定义发送到数据源控件的信息
GridView 对象模型
GridView 与 DataGrid 的整体结果看起来相似一些通用元素经过了重命名一些通用功能现在需要不同的语法总之如果熟悉 DataGrid 控件则可立即自如地运用 GridView图 详尽列出了组成 GridView 的新元素(请注意其中一些元素如 DetailLinkStyle仅用于在移动设备上显示网格)行元素通过 Rows 集合中的 GridViewRow 类生成的实例进行显示GridViewRow 类映射到 DataGridItem 类而 Rows 明确替代了 DataGrid 的项目集合行类型由 DataControlRowType 枚举表示用来指示位置和角色(例如页脚页眉页导航和数据行)GridView 还引入一个新概念 — 行元素状态该行状态由 DataControlRowState 标记的枚举值表示 — 通常值是 Edit可选值为 Insert 和 Selected有趣的是这两类枚举恰巧由所有数据视图控件(GridViewDetailsView 和 FormView)共享
除了引入符合自适应显示的元素之外GridView 仅有一个其他类型的新元素 — 空数据行当 GridView 绑定到一个空数据源时会选择性地显示一些默认内容为用户提供反馈在这种情况下显示的内容依赖于新的空数据行元素的内容可通过一个属性 (EmptyDataText) 或一个模板 (EmptyDataTemplate) 设置该行的内容
GridView 控件的属性主要分为三种类型行为可视设置和状态图 列出 GridView 的一些属性请查看包括 EnableSortingAndPagingCallbacksEmptyDataText 和 UseAccessibleHeader 在内的新属性以及被重命名或改编的属性后者实现了 DataGrid 已经支持的功能
编程模型与按钮列略有不同在 ASPNET x 的 DataGrid 中您不得不通过添加特定的列类型来创建一个 Edit 按钮 — EditCommandColumn如果要创建一个 Delete 或 Select 按钮列则必须添加通用的按钮列并预定义一个命令名GridView 对象则更一致更简洁它基于三个新的布尔属性AutoGenerateEditButtonAutoGenerateDeleteButton 和 AutoGenerateSelectButton当其中任何一个属性设置为真时网格中分别添加一个 EditDelete 或 Select 命令按钮列例如当 AutoGenerateEditButton 属性设置为真时在网格中自动为每个数据行添加带有 Edit 按钮的一列也可以手动添加这些按钮方法是在列集合中添加一个 CommandField 对象Columns 属性列出了列对象这些对象很像 DataGrid 的 Columns 属性列出的对象根据客户的反馈其中也添加了几个帮助器属性特别是您现在能够为每个显示行存储多个键值实际上DataGrid 的 DataKeyField 字符串属性已经扩展为一个字段名数组新的属性命名为 DataKey用于存储由字段名组成的一个字符串数组这个字符串数组唯一标识一个数据行DataKey 是特定行的值的相应数组它返回 DataKey 对象的集合每个 DataKey 对象包含一个键名值DataKey 的 DataKey 对象数量与 GridView 的显示行数相同
SortDirection 和 SortExpression 跟蹤当前的网格排序这些属性用于在内部实现自动翻转排序标记网格当前排序次序每个对象的 PagerSettings 组包含配置用户界面行为和页导航位置的所有属性现在页导航支持的导航模式不但包括首行和尾行还包括下一行和上一行
GridView 控件也能够使用一个基于回调的轻量型机制来进行排序和分页您可以通过设置 EnableSortingAndPagingCallbacks 布尔属性来开启和关闭此功能当单击排序或分页链接来启用回调时GridView 请求排序数据或下一页不回发可视页面(这里发生了一个往返过程但是无页面刷新因此您不知道)请注意这个功能有个警告启用 GridView 中的选项时新页面保留当前选定的索引如果有与之相关联的详细信息页面那么选定的内容将失去同步处理类似 PageIndexChanging 这样的事件也不管用因为如果不启用回调则不能引发这些事件最后切记回调驱动的分页和排序机制需要使用 Microsoft Internet Explorer 及更高版本
GridView 事件
GridView 控件使用的方法与我们熟知的 DataBind 方法不同在 ASPNET 中许多控件以及 Page 类本身使用的是 Preload/Postload 事件对控件生命周期中的关键操作被包装在一对事件中一个在操作发生前触发另一个在操作完成后立即触发GridView 类也是这样图 显示的是新事件列表使用事件来通告操作极大地增强了编程能力例如通过挂钩 RowUpdating 事件您能够检查新值的更新内容您可能想在客户端提供的值存留到下层数据存储之前通过 HTML 编码来处理 RowUpdating 事件这种简单的技巧有助于避免恶意的脚本注入
使用 pre/post 事件对使您能够取消一个基于运行时条件而进行的事件请看以下代码片段
voidPageIndexChanging(objectsender
GridViewPageEventArgse)
{
//Isthisthesensitivepage?(>)
boolisSensitivePage=(eNewPageIndex>);
if(isSensitivePage&&(UserIdentityName!=username))
eCancel=true;
return;
}
取消是一个读/写布尔属性存在于所有从 CancelEventArgs 派生的事件参数类中GridView 的许多事件参数类继承了 CancelEventArgs这意味着所有这些事件都能被取消Cancel 属性值在激发pre事件时通常设置为假处理事件时您能够检查一些条件通过将 Cancel 属性设置为真选择取消事件例如刚才的代码片段在当前用户未被授权查看索引大于 的页面时取消了转换到新页面的操作
显示排序和分页
一个网格通常用于显示数据库查询的结果使用 GridView 控件显示结果比以往更简单您只需建立一个数据源对象提供连接字符串和查询文本为 GridView 的 DataSourceId 属性分配数据源 ID运行时GridView 自动绑定到数据源生成正确的数据列在默认情况下查询的所有列均显示在网格中
像 DataGrid 控件一样GridView 也支持在 Columns 集合中自定义列字段如果只想显示检索到的数据字段的一个子集或只想自定义其显示外观则可使用代表显示数据列的对象来填充 Columns 集合GridView 支持多种列类型包括新的复选框和图像列类型
<columns>
<asp:boundfielddatafield=productnameheadertext=Product/>
<asp:checkboxfielddatafield=discontinued
headertext=Discontinued/>
<asp:buttonfieldbuttontype=Buttontext=Buy/>
<asp:hyperlinkfieldtext=MoreInfo
datanavigateurlfields=productiddiscontinued
datanavigateurlformatstring=moreaspx?id={}&disc={}/>
</columns>
图 显示的活动网格配置为使用代码中列出的字段GridView 列类名与 DataGrid 接口中的相应类名略有不同后缀column基本被替换成后缀field除了名字的更改与列类匹配的行为几乎相同一些新的列类型使您不必经常使用模板例如CheckBoxField 列通过一个复选框显示特定的数据字段而改进的 HyperLinkField 列提供了期待已久的功能 — 支持多个 URL 参数正如刚才的代码片段所示DataNavigateUrlFields 属性接收了一个以逗号分隔的字段名列表并将其合并到 DataNavigateUrlFormatString 属性的文本中
图带有活动字段的GridView
请注意 ButtonField 与 CommandField 之间的差异两列都向网格的用户界面添加了一个按钮但是 CommandField 用于显示命令按钮来执行选择编辑插入或删除操作ButtonField 只是代表作为按钮显示的字段最后GridView 能够通过 ImageField 列类型嵌入图像
<aspimagefield datafield=photo headertext=Picture />
图 显示活动的 ImageField 列它位于 Northwind 雇员表的照片字段有趣的是ImageField 通过 ASPNET DynamicImage 控件显示来自数据库和 URL 两者的图像而且在编辑模式下ImageField 列弹出一个 Browse 按钮用于定位要上载的位于本机的新文件
图图像字段列
Template列也受支持所需的语法与ASPNETx的DataGrid使用的相似
<asp:templatefieldheadertext=Product>
<itemtemplate>
<b><%#Eval(productname)%></b><br/>
availablein<%#Eval(quantityperunit)%>
</itemtemplate>
</asp:templatefield>
有趣的是ASPNET 允许的数据绑定表达式的语法更简洁在 ASPNET x 中生成模板化的内容需要使用下列表达式 DataBinderEval(ContainerDataItem fieldname)由于使用了一个更小的数据绑定机制现在您能够避免使用 DataBinder 类中静态的 Eval 方法而是调用 Page 类定义的新的 Eval 保护方法您将计算的字段名和方法传递给 Eval决定当前的数据项并通过 DataBinderEval 准备一个常规调用
Eval 被声明为 TemplateControl 类的一个保护方法Page 和 UserControl 都从这个类派生真正代表一个 aspx 活动页面的类是从 Page 派生的一个类的实例因此它能够调入受保护的方法ASCX 用户控件也是如此
如果焦点是显示纯数据则不需要像 GridView 这样全新的网格控件当然现在您只需少量代码或不需要编码就能将数据源控件绑定到 GridView但是单凭这点就有必要替换 DataGrid 吗?如果答案是否定的请考虑排序和分页
在 GridView 控件中只需通过开启 AllowPaging 和 AllowSorting 属性就能启用自动翻转排序和分页功能如果在 ASPNET x 中尝试过这项操作您就可大概了解这项功能了
图活动的可分页可排序网格
图 显示一个可分页可排序的网格图 显示此网格的完整代码(值得注意的是仅当需要标记列标头来指示排序方向时才需要使用 C# 代码)因此无需编写代码排序和分页就能十分正常地运行通过 DataSourceMode 属性控制 SQLDataSource 的数据检索模型可行的值类型是 DataSet(默认值)和 DataReader当 DataSourceMode 为 DataSet 时数据源控件可能会一直选择性地缓存 SELECT 命令的结果这使得 GridView 适应于丰富多样的使用情境其中控件可提供无代码排序筛选和分页功能默认情况下禁用缓存因此它必须在数据源控件上启用
在内存中缓存数据能大大提高性能但是数据会显得有些脆弱您必须权衡利弊因为如果系统内存运行效率低Cache 对象会自动丢弃最少使用的数据此外在 ASPNET 中SQLDataSource 控件可能选择性地建立与数据库的自动依赖关系以便立即检测到数据变更这确保了总是显示最新的数据有关数据源控件功能的更多信息请参见我在前面提到的 年 月发表的文章当 SQLDataSource 控件检索模型为 DataReader 时检索数据使用 IDataReader 对象它是一个只进只读流水游标
编辑数据
DataGrid 控件最大的缺点之一 — 相反却是 GridView 控件最大的优点之一是处理数据源更新的能力当绑定数据源支持更新时GridView 能够自动执行数据操作从而提供真正的出盒解决方案数据源控件通过一些布尔属性(例如 CanUpdateCanDeleteCanSort 等)提供这些功能
对 GridView 控件而言数据编辑意味着就地编辑和记录删除如前所述就地编辑指网格支持更改当前显示记录的功能启用 GridView 的就地编辑需要启动 AutoGenerateEditButton 布尔属性
<asp:gridviewrunat=serverid=MyGridView
datasourceid=MySource
autogenerateeditbutton=true>
&S;&S;&S;
</asp:gridview>
当 AutoGenerateEditButton 属性设置为真时GridView 显示附加的一列如图 中最左边一列单击一行的 Edit 按钮将此行置于编辑模式下当一行处于编辑模式下时非只读行的每个绑定字段将显示适当的输入控件通常是一个 TextBox当您单击更新时GridView 引发 RowUpdating 事件并检查数据源的 CanUpdate 属性如果 CanUpdate 返回值为假则引发一个异常否则在数据源对象的 UpdateCommand 属性后创建和配置一个命令对象
图GridView的Edit列
即使您对 SQL 的操作仅限于定义命令结构 — 只定义语句而让控件来完成其他操作也无需使用 ADONET 或担心如何使用命令或连接想在用户单击 Update 时保留更改可编写以下代码
<asp:sqldatasourcerunat=serverid=MySource
connectionstring=SERVER=;DATABASE=northwind;Integrated
Security=SSPI;
updatecommand=UPDATEemployeesSET
firstname=@firstnamelastname=@lastname
WHEREemployeeid=@employeeid>
</asp:sqldatasource>
<asp:gridviewrunat=serverid=MyGridView
DataSourceId=MySource
DataKeyNames=employeeidAutoGenerateEditButton=true>
&S;&S;&S;
</asp:gridview>
数据源的 UpdateCommand 属性被设置为 GridView 使用的 SQL 命令您能够使用所需的任意数量的参数如果您采用一种特殊的命名规则参数值也能够自动解析代表更新字段的参数(例如 firstname)必须与网格列的 DataField 属性名相匹配用于标识工作记录的 WHERE 子句中使用的参数必须与 DataKeyNames 属性匹配后者是显示记录的关键字段最后考虑这种情况如果没有定义 UpdateCommand却提交更改那么 CanUpdate 返回值为假并引发一个异常RowUpdated 事件发出信号通知更新命令结束通过更新命令更新的行数可在 RowUpdated 事件参数的 AffectedRows 属性中检索
GridView 自动收集输入字段的值填充 name/value 对词典这个词典指示了每个行字段的新值GridView 也公开一个 RowUpdating 事件允许您修改正在传递到数据源对象的值此外在相关数据源上激发 Update 操作前GridView 将自动调用 PageIsValid如果 PageIsValid 返回值为假将取消操作这对使用包括验证程序在内的自定义编辑模板特别有用
行删除操作方式与此相似下面的 SQL 命令是一个数据源对象的 DeleteCommand 属性的合法内容DELETE employees WHEREemployeeid=@employeeid请注意如果由于特定于数据库的约束而无法删除记录删除操作将失败例如如果子记录通过某种关系引用父记录父记录将无法删除在这种情况下引发一个异常
GridView 控件不自动支持向数据源插入数据没有这项功能完全是由于实现 GridView 不依赖于底层数据源的功能和特性实际上数据源对象提供一个 CanInsert 属性并支持一个 InsertCommand 属性请注意通过 GridView 和 DetailsView 控件的组合能够实现这个功能一会您就会了解到
DetailsView控件
许多应用程序需要一次作用于一条记录在 ASPNET x 中没有内置的功能支持这种情况创建单条记录视图是可能的但需要您自己编写代码首先您需要获取记录然后将字段绑定到数据绑定表单选择性地提供分页按钮来浏览记录我编写了三个 Cutting Edge 列的安装程序来解决这个问题 — 年 月 月和 月
当生成主/详细视图时经常需要显示单条记录的内容通常用户从网格中选择一条主记录让应用程序追溯所有可用字段通过组合 GridView 和 DetailsView编写少量代码就能够生成有层次结构的视图
DetailsView 控件能够自动绑定到任何数据源控件使用其数据操作集控件能够自动分页更新插入和删除底层数据源的数据项只要数据源支持这些操作多数情况下建立这些操作无需编写代码如下所示
<asp:detailsviewrunat=serverid=det
datasourceid=MySource
autogenerateeditbutton=true
autogenerateinsertbutton=true
autogeneratedeletebutton=true
allowpaging=true
headertext=Employees>
<pagersettingsmode=NextPreviousFirstLast
firstpageimageurl=images/firstgif
lastpageimageurl=images/lastgif
nextpageimageurl=images/nextgif
previouspageimageurl=images/prevgif/>
</asp:detailsview>
DetailsView 控件的用户界面能够通过使用数据字段和类型进行自定义其方式与 GridView 相似DetailsView 不支持自定义模板因为这项特殊的功能完全构造在新的 FormView 控件中DetailsView 具有一个命令栏显示 EditDelete 和 New 按钮的任意组合当您单击 Edit 或 New 时控件显示 Edit 或 Insert 模式字段内容显示在文本框中工作模式能通过 Mode 和 DefaultMode 属性控制
使用 DetailsView 控件能很好地实现无需代码的主/详细视图除了 Edit 和 Delete 按钮GridView 控件支持 Select 按钮它也是预定义的通过设置 AutoGenerateSelectButton 属性为真您能为每一行启用此按钮当用户单击此按钮时当前行输入选定状态为 GridView 的 SelectedIndex 属性分配从 开始的索引值此外GridView 控件引发 SelectedIndexChanged 事件应用程序可以挂钩到这个事件并执行自定义代码
在 ASPNET 中如果您想生成主/详细视图则无需处理 SelectedIndexChanged 事件您可以将一个 GridView 控件和一个 DetailsView 控件拖放到页面上将两者绑定到一个数据源生成无代码的主/详细视图的技巧是将详细视图控件绑定到当前选定记录所代表的数据源如下所示
<asp:sqldatasourcerunat=serverid=MyDetailSource
&S;&S;&S;
selectcommand=SELECT*FROMcustomers
filterexpression=customerid=@customerid>
<filterparameters>
<asp:ControlParameterName=customerid
ControlId=masterGrid
PropertyName=SelectedValue/>
</filterparameters>
</asp:sqldatasource>
对象的FilterExpression属性为SelectCommand指定的基础查询定义WHERE子句参数值能够以多种方式指定包括直接绑定一个控件属性对象将@customerid参数设置为主网格控件的SelectedValue属性存储的值图的代码显示如何配置主网格控件和详细视图控件图显示活动页面请注意无需程序代码来完成这些功能
图活动主网格
FormView控件
FormView 是新的数据绑定控件使用起来像是 DetailsView 的模板化版本它每次从相关数据源中选择一条记录显示选择性地提供分页按钮用于在记录之间移动与 DetailsView 控件不同的是FormView 不使用数据控件字段而是允许用户通过模板定义每个项目的显示FormView 支持其数据源提供的任何基本操作
FormView 控件是作为通常使用的更新和插入接口而设计的它不能验证数据源架构不支持高级编辑功能比如外键字段下拉然而使用模板来提供此功能很容易FormView 和 DetailsView 有两方面的功能差异首先FormView 控件具有 ItemTemplateEditItemTemplate 和 InsertItemTemplate 属性而 DetailsView 一个也没有其次FormView 缺少命令行 — 将可用功能进行分组的工具栏与 GridView 和 DetailsView 控件不同的是FormView 没有其自己默认的显示布局同时它的图形化布局完全是通过模板自定义的因此每个模板都包括特定记录需要的所有命令按钮下列代码片断是在页面中嵌入一个 FormView 的典型写法
<asp:FormViewID=EmpDetailsrunat=server
DataSourceId=MySourceAllowPaging=true>
<ItemTemplate>
&S;&S;&S;
</ItemTemplate>
<EditItemTemplate>
&S;&S;&S;
</EditItemTemplate>
<InsertItemTemplate>
&S;&S;&S;
</InsertItemTemplate>
</asp:FormView>
图 说明一个使用 FormView 控件的页面Edit 按钮通过命令名 Edit 的 <aspButton> 元素来添加这将导致 FormView 从只读模式转换到编辑模式使用定义过的 EditItemTemplate 显示New 命令名将强制控件转换为插入模式显示 InsertItemTemplate 的定义内容最后如果您将命令名为 Delete 的按钮添加到项目模板中用户单击它时FormView 将调用数据源的 Delete 命令
图FormView控件
如何检索数据来更新或插入一条记录?您可以使用一个新的数据绑定关键字 Bind它是专门为双向绑定而设计的Bind 关键字像 Eval 一样用于显示数据而且能在更新或插入一条记录时检索输入值此外Bind 对 GridView 和 DetailsView 使用的 TemplateFields 非常有用
Bind 将绑定控件属性值存入一个值集合FormView 控件自动检索和使用这个集合来组合插入或编辑命令的参数列表传递到 Bind 的参数必须与数据容器的字段名匹配例如上一个代码片断中的文本框存放备注字段的值最后还要记住的是编辑和插入模板必须包含保存变更的按钮这是指普通的按钮 — 用于保存的 Update 和 Insert 以及用于放弃操作的 Cancel FormView 事件的工作方式与 DetailsView 和 GridView 相同因此如果想处理像数据预处理或后处理(例如填充下拉框)这样更复杂的操作您应该为 ItemCommandItemInserting 和 ModeChanging 之类的事件编写适当的事件处理程序
小结
数据绑定控件是大多数 Web 应用程序的必要组成部分数据绑定控件应该简单但功能强大理想的情况是它们应该以很少的单击操作以及有限的代码数量提供高级的功能虽然 ASPNET 仍然在使用但是其新一代的数据绑定控件满足了这个需求ASPNET x 数据绑定的主要缺点是需要为普通数据操作编写过多的代码这一点已经随着数据源对象和 GridView 控件的引入而解决了DetailsView 和 FormView 是对 GridView 的完美补充代表了对 ASPNET x 数据工具箱的重大改进