专题 |  新闻 |  转载文档 |  控件 |  产品 |  人才 |  项目管理 |  博客  
 论坛 |  Windows |  Visual Studio |  ASP.NET |  VB.NET |  C#.NET |  开源项目 |  搜索  
当前所在位置:首页.NET 控件  >  正文
专题: 软件 | 服务器 | IT 电子产品 | PC 电脑 | 笔记本 | IE7 | Windows Mobile | Windows 2003 Server | ISA 2006 | Windows Vista
ASP.Net2.0 数据绑定控件的优越性(一)
作者:.NET 控件 发布时间:20070123 文章来源:
   尽管有丰富、功能强大的编程接口,ASP.NET 1.x DataGrid 控件仍需要编写大量自定义代码来处理普通操作,如分页、排序、编辑和删除数据。例如,当用户单击以保存或取消更改时,DataGrid 控件能够引发事件但不提供更多的功能。如果要将更改存储到持续媒介(如一个数据库)之中,则必须自己处理 UpdateCommand 事件,检索更改后的值,编写一条 SQL 命令,然后从该处提交更新。

DataGrid 控件限制普通数据操作的引发事件,因为它是一个数据源不可知的控件,能够绑定到任何可枚举的数据对象。执行数据操作(如更新或删除)需要直接连接到一个特定的数据源。在 ASP.NET 1.x 中,则通过编写特定于应用程序的 ADO.NET 代码解决这个问题的。

ASP.NET 2.0 改进了数据绑定体系结构,引入了新的系列组件(数据源对象)作为数据绑定控件与 ADO.NET 对象之间的桥梁。这些源对象提升了一个略为不同的编程模型,提供了新功能和新成员。您的 ASP.NET 2.0 应用程序应该使用最新的网格控件 — GridView,显示数据报告。与之相似的 DataGrid 控件仍然支持,但 DataGrid 不能充分利用数据源组件的特定功能。

GridView 控件是 DataGrid 的接替者,并从几个方面扩展了后者的功能。首先,它完全支持数据源组件,能够自动处理诸如分页、排序和编辑等数据操作,前提是绑定的数据源对象支持这些操作。另外,GridView 控件有一些比 DataGrid 优越的功能上的改进。特别是,它支持多个主键字段,公开了一些用户界面的改进功能和一个处理与取消事件的新模型。

GridView 附带了一对互补的视图控件:DetailsView 和 FormView。通过这些控件的组合,您能够轻松地建立主/详细视图,而只需少量代码,有时根本不需要代码。

GridView 与 DataGrid


ASP.NET 2.0 中数据绑定控件的类层次结构比 ASP.NET 1.x 中的更一致。在 2.0 版本中,所有控件无论有什么样的实际实现过程和用户界面特点,均从同一个基类(BaseDataBoundControl 类)派生。图 1 显示新的类关系图。DataGrid 和其他 1.x 版本的控件(如 Repeater 和 DataList)没有包含在该关系图中。这些现有控件的继承树与 ASP.NET 1.x 的相同。特别是,Repeater 继承了 WebControl,而 DataList 和 DataGrid 继承了 BaseDataList。如图 1 所示,GridView 是一个复合数据绑定控件,它与其他所有数据绑定控件(包括 DropDownList、DetailsView 和 ListBox)共享一组方法和属性。


按此在新窗口打开图片
图 1 ASP.NET 类关系图


GridView 和 DataGrid 控件的高级功能相似,但基础却不同。GridView 尽可能地保留了 DataGrid 的对象模型,以便轻松地从现有页面进行移植。但是,基于 DataGrid 的代码与新的基于 GridView 的代码不可能 100% 兼容。

DataGrid 与 GridView 控件的另一个主要差异在于自适应用户界面。与 1.x 版本的 DataGrid 不同的是,GridView 也能在移动设备上显示。换句话说,您能够使用相同的用于桌面页面的网格控件在移动设备上生成报告。2.0 版本的 DataGrid 也能自适应地显示,但是它的 UI 功能没有 GridView 丰富。

在 ASP.NET 2.0 中,改进后的 DataGrid 控件支持诸如主题和个性化等通用的控件功能。此外,新的 DataGrid 控件可由一个数据源控件填充。但要记住,绑定到数据源对象的 DataGrid 只能用于读取数据。要实际修改底层数据源,仍然需要一些用户定义的代码。而 GridView 控件可以利用底层数据源的功能并自动删除或更新记录。注意,GridView 控件也支持传统的基于 DataSource 属性和 DataBind 方法的绑定机制。尽管完全支持这种绑定机制,但是不鼓励使用这样的编程实践方法。


GridView 和数据源控件


那么,数据源控件是什么?我在 2004 年 6 月一期的 MSDN®Magazine 中详细介绍了 ASP.NET 2.0 的这项流行的新功能。简言之,一个数据源控件就是一组 Microsoft® .NET Framework 类,它有利于数据存储和数据绑定控件之间的双向绑定。现有的控件(如 DataGrid)以及新的数据绑定控件(如 GridView),尽管绑定能力不同,但都能绑定到一个数据源。

一个数据源控件代表了数据源的主要功能:选择、插入、更新和删除。数据源控件能代表任何数据源:从关系数据源库到 XML 文件,从流数据到业务对象。如果简要介绍能让您想起 .NET 的托管提供程序,请参见图 2。


按此在新窗口打开图片
图 2 数据源控件、GridView 和数据源


数据源控件可以位于一些 .NET 数据提供程序的上层,在数据绑定控件和数据源之间形成一个中间层。数据源控件也会公开一个提供基本操作的公共接口。一些数据绑定控件 — 特别是 GridView 控件,将这些命令与其他与数据有关的操作一起,绑定到适当的自动编辑。

数据源控件通过其属性和方法,将绑定内容以一组命名的视图形式公开。IDataSource 接口提供从数据源检索数据视图的基本功能集,所有数据源控件都实现了这个接口。ASP.NET 2.0 提供一些内置数据源控件,如图 3 所列。图 3列出的数据源控件属于两类:列表和分层组件。SiteMapDataSource 和 XmlDataSource 组件是分层数据源控件,用于像 TreeView 和 Menu 控件这样的分层组件。其他各种组件用于管理列表数据。

图 4 中的代码说明如何在一个示例页面上将 GridView 和 DataGrid 绑定到同一个数据源控件。在 ASP.NET 2.0 中,这是推荐的数据绑定方法。SqlDataSource 控件的特点是一个 ConnectionString 属性加上 SelectCommand、UpdateCommand、InsertCommand 和 DeleteCommand 属性的任意组合。所有属性都是字符串形式,并且引用带有可选参数的命令文本: 

<asp:SqlDataSource runat="server" 
  ID="MySource" 
  ConnectionString="SERVER=(local);
  DATABASE=northwind;Integrated Security=SSPI;"
  SelectCommand="SELECT * FROM employees WHERE employeeid > @MinID">
  <SelectParameters>
     <asp:ControlParameter Name="MinID" 
          ControlId="EmpID" 
          PropertyName="Text" />
  </SelectParameters>
</asp:SqlDataSource>
 

每个数据源控件由唯一的 ID 表示。ID 是连结数据绑定控件和数据源控件之间的纽带。通过 DataSourceId 属性将 GridView 绑定到一个数据源控件。例如,每当网格需要获取数据时,就执行与 SQLDataSource 控件相关联的 SelectCommand SQL 命令。当网格需要更新或删除一条记录时,就执行相应的 UpdateCommand 或 DeleteCommand SQL 命令。如果不存在这样的命令,则引发一个异常。在内部,当用户删除或更新一条记录时,GridView 就像 1.x 版本的 DataGrid 一样引发事件。但是与 DataGrid 不同的是,GridView 为这些事件定义内部的处理程序。默认的处理程序检索绑定数据源定义的命令来处理和执行这些操作。图 4说明,在保持网格显示或更新数据的标记后无需编写代码。在更复杂的情况下,您可能需要编写一些代码。


按此在新窗口打开图片
图 5 GridView 和 DataGrid


数据源控件和 GridView 控件通常用于无代码数据绑定。图 5 显示图 4的代码生成的输出结果。

在 ASP.NET 2.0 中,除了 DataSource 和 DataMember,DataGrid 还公开了 DataSourceId 属性。DataSourceId 属性将 DataGrid 连接到同一页面上定义的一个合法数据源对象。但是,DataGrid 不提供与 GridView 同一级别的自动化操作。当用户单击以更新一条记录时,DataGrid 引发 UpdateCommand 事件,而 GridView 除了引发 Updating 和 Updated 事件外,还检索和执行数据源更新命令,允许用户自定义发送到数据源控件的信息。


GridView 对象模型


GridView 与 DataGrid 的整体结果看起来相似。一些通用元素经过了重命名,一些通用功能现在需要不同的语法。总之,如果熟悉 DataGrid 控件,则可立即自如地运用 GridView。图 6 详尽列出了组成 GridView 的新元素(请注意,其中一些元素,如 DetailLinkStyle,仅用于在移动设备上显示网格)。行元素通过 Rows 集合中的 GridViewRow 类生成的实例进行显示。GridViewRow 类映射到 DataGridItem 类,而 Rows 明确替代了 DataGrid 的项目集合。行类型由 DataControlRowType 枚举表示,用来指示位置和角色(例如,页脚、页眉、页导航和数据行)。GridView 还引入一个新概念 — 行元素状态。该行状态由 DataControlRowState 标记的枚举值表示 — 通常值是 Edit,可选值为 Insert 和 Selected。有趣的是,这两类枚举恰巧由所有数据视图控件(GridView、DetailsView 和 FormView)共享。

除了引入符合自适应显示的元素之外,GridView 仅有一个其他类型的新元素 — 空数据行。当 GridView 绑定到一个空数据源时,会选择性地显示一些默认内容,为用户提供反馈。在这种情况下显示的内容依赖于新的空数据行元素的内容。可通过一个属性 (EmptyDataText) 或一个模板 (EmptyDataTemplate) 设置该行的内容。

GridView 控件的属性主要分为三种类型:行为、可视设置和状态。图 7 列出 GridView 的一些属性。请查看包括 EnableSortingAndPagingCallbacks、EmptyDataText 和 UseAccessibleHeader 在内的新属性以及被重命名或改编的属性,后者实现了 DataGrid 已经支持的功能。

编程模型与按钮列略有不同。在 ASP.NET 1.x 的 DataGrid 中,您不得不通过添加特定的列类型来创建一个 Edit 按钮 — EditCommandColumn。如果要创建一个 Delete 或 Select 按钮列,则必须添加通用的按钮列并预定义一个命令名。GridView 对象则更一致、更简洁。它基于三个新的布尔属性:AutoGenerateEditButton、AutoGenerateDeleteButton 和 AutoGenerateSelectButton。当其中任何一个属性设置为真时,网格中分别添加一个 Edit、Delete 或 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 5.0 及更高版本。


GridView 事件


GridView 控件使用的方法与我们熟知的 DataBind 方法不同。在 ASP.NET 2.0 中,许多控件以及 Page 类本身使用的是 Pre-load/Post-load 事件对。控件生命周期中的关键操作被包装在一对事件中,一个在操作发生前触发,另一个在操作完成后立即触发。GridView 类也是这样。图 8 显示的是新事件列表。使用事件来通告操作极大地增强了编程能力。例如,通过挂钩 RowUpdating 事件,您能够检查新值的更新内容。您可能想在客户端提供的值存留到下层数据存储之前,通过 HTML 编码来处理 RowUpdating 事件。这种简单的技巧有助于避免恶意的脚本注入。

使用 pre/post 事件对使您能够取消一个基于运行时条件而进行的事件。请看以下代码片段: 

void PageIndexChanging(object sender, GridViewPageEventArgs e)
{
  // Is this the sensitive page? (> 4)
  bool isSensitivePage = (e.NewPageIndex > 4);
  if (isSensitivePage && (User.Identity.Name != "username"))
     e.Cancel = true;
  return;    
}

取消是一个读/写布尔属性,存在于所有从 CancelEventArgs 派生的事件参数类中。GridView 的许多事件参数类继承了 CancelEventArgs,这意味着所有这些事件都能被取消。Cancel 属性值在激发“pre”事件时通常设置为假。处理事件时,您能够检查一些条件,通过将 Cancel 属性设置为真选择取消事件。例如,刚才的代码片段在当前用户未被授权查看索引大于 4 的页面时,取消了转换到新页面的操作。 


显示、排序和分页


一个网格通常用于显示数据库查询的结果。使用 GridView 控件显示结果比以往更简单。您只需建立一个数据源对象,提供连接字符串和查询文本,为 GridView 的 DataSourceId 属性分配数据源 ID。运行时,GridView 自动绑定到数据源,生成正确的数据列。在默认情况下,查询的所有列均显示在网格中。

像 DataGrid 控件一样,GridView 也支持在 Columns 集合中自定义列字段。如果只想显示检索到的数据字段的一个子集,或只想自定义其显示外观,则可使用代表显示数据列的对象来填充 Columns 集合。GridView 支持多种列类型,包括新的复选框和图像列类型: 

<columns>
  <asp:boundfield datafield="productname" headertext="Product" /> 
  <asp:checkboxfield datafield="discontinued" 
     headertext="Discontinued" /> 
  <asp:buttonfield buttontype="Button" text="Buy" /> 
  <asp:hyperlinkfield text="More Info..." 
     datanavigateurlfields="productid,discontinued"
     datanavigateurlformatstring="more.aspx?id={0}&disc={1}" /> 
</columns>
 

图 9 显示的活动网格配置为使用代码中列出的字段。GridView 列类名与 DataGrid 接口中的相应类名略有不同。后缀“column”基本被替换成后缀“field”。除了名字的更改,与列类匹配的行为几乎相同。一些新的列类型使您不必经常使用模板。例如,CheckBoxField 列通过一个复选框显示特定的数据字段,而改进的 HyperLinkField 列提供了期待已久的功能 — 支持多个 URL 参数。正如刚才的代码片段所示,DataNavigateUrlFields 属性接收了一个以逗号分隔的字段名列表,并将其合并到 DataNavigateUrlFormatString 属性的文本中。 

按此在新窗口打开图片
图 9 带有活动字段的 GridView


请注意 ButtonField 与 CommandField 之间的差异。两列都向网格的用户界面添加了一个按钮,但是 CommandField 用于显示命令按钮来执行选择、编辑、插入或删除操作。ButtonField 只是代表作为按钮显示的字段。最后,GridView 能够通过 ImageField 列类型嵌入图像。 

<asp:imagefield datafield="photo" headertext="Picture" />

图 10 显示活动的 ImageField 列,它位于 Northwind 雇员表的照片字段。有趣的是,ImageField 通过 ASP.NET 2.0 DynamicImage 控件显示来自数据库和 URL 两者的图像。而且,在编辑模式下,ImageField 列弹出一个 Browse 按钮,用于定位要上载的位于本机的新文件。 


按此在新窗口打开图片
图 10 图像字段列


Template 列也受支持,所需的语法与 ASP.NET 1.x 的 DataGrid 使用的相似: 

<asp:templatefield headertext="Product">
   <itemtemplate>
     <b><%# Eval("productname")%></b> <br />
     available in <%# Eval("quantityperunit")%>
  </itemtemplate>
</asp:templatefield>
 

有趣的是,ASP.NET 2.0 允许的数据绑定表达式的语法更简洁。在 ASP.NET 1.x 中生成模板化的内容需要使用下列表达式: DataBinder.Eval(Container.DataItem, "fieldname")由于使用了一个更小的数据绑定机制,现在,您能够避免使用 DataBinder 类中静态的 Eval 方法,而是调用 Page 类定义的新的 Eval 保护方法。您将计算的字段名和方法传递给 Eval,决定当前的数据项并通过 DataBinder.Eval 准备一个常规调用。 

Eval 被声明为 TemplateControl 类的一个保护方法,Page 和 UserControl 都从这个类派生。真正代表一个 .aspx 活动页面的类是从 Page 派生的一个类的实例;因此,它能够调入受保护的方法。ASCX 用户控件也是如此。

如果焦点是显示纯数据,则不需要像 GridView 这样全新的网格控件。当然,现在您只需少量代码或不需要编码就能将数据源控件绑定到 GridView,但是单凭这点就有必要替换 DataGrid 吗?如果答案是否定的,请考虑排序和分页。

在 GridView 控件中,只需通过开启 AllowPaging 和 AllowSorting 属性就能启用自动翻转排序和分页功能。如果在 ASP.NET 1.x 中尝试过这项操作,您就可大概了解这项功能了。

按此在新窗口打开图片
图 11 活动的可分页、可排序网格


图 11 显示一个可分页、可排序的网格。图 12 显示此网格的完整代码。(值得注意的是,仅当需要标记列标头来指示排序方向时才需要使用 C# 代码。)因此,无需编写代码,排序和分页就能十分正常地运行。通过 DataSourceMode 属性控制 SQLDataSource 的数据检索模型。可行的值类型是 DataSet(默认值)和 DataReader。当 DataSourceMode 为 DataSet 时,数据源控件可能会一直选择性地缓存 SELECT 命令的结果。这使得 GridView 适应于丰富多样的使用情境,其中控件可提供无代码排序、筛选和分页功能。默认情况下禁用缓存,因此它必须在数据源控件上启用。

在内存中缓存数据能大大提高性能,但是数据会显得有些脆弱。您必须权衡利弊,因为如果系统内存运行效率低,Cache 对象会自动丢弃最少使用的数据。此外,在 ASP.NET 2.0 中,SQLDataSource 控件可能选择性地建立与数据库的自动依赖关系,以便立即检测到数据变更。这确保了总是显示最新的数据。有关数据源控件功能的更多信息,请参见我在前面提到的 2004 年 6 月发表的文章。当 SQLDataSource 控件检索模型为 DataReader 时,检索数据使用 IDataReader 对象,它是一个只进、只读、流水游标。


编辑数据


DataGrid 控件最大的缺点之一 — 相反却是 GridView 控件最大的优点之一,是处理数据源更新的能力。当绑定数据源支持更新时,GridView 能够自动执行数据操作,从而提供真正的出盒解决方案。数据源控件通过一些布尔属性(例如 CanUpdate、CanDelete、CanSort 等)提供这些功能。

对 GridView 控件而言,数据编辑意味着就地编辑和记录删除。如前所述,就地编辑指网格支持更改当前显示记录的功能。启用 GridView 的就地编辑,需要启动 AutoGenerateEditButton 布尔属性: 

<asp:gridview runat="server" id="MyGridView" 
   datasourceid="MySource" 
   autogenerateeditbutton="true">
   &S226;&S226;&S226;
</asp:gridview>
转载文档
.NET
Visual Basic
Visual C++
游戏开发
Java
ASP
Perl
Delphi
Javascript
其他开发语言
数据库开发
网站制作技术
文件格式
其他
文章投稿
Web.Service
ASP.Net
C#.Net
VB/VC.Net
Borland
JAVA
数据库
Unix/Linux
图形美工
安全
VS.Net

中国DotNet俱乐部 || 博客.中国  版权所有
京ICP备05037360号