使用 ObjectDataSource 显示数据

本文档是 Visual C# 教程 (切换到 Visual Basic 教程)

该教程介绍 ObjectDataSource 控件,使用该控件,无需编写一行代码就可以绑定由前面教程创建的 BLL 检索的数据

« 前一篇教程  |  下一篇教程 »

简介

有了完整的应用程序体系结构和网站页面布局,我们就可以开始研究如何实现与任务相关的各种常用数据和报表。前面的教程中,已经介绍了如何通过编程将来自 DAL 和 BLL 的数据绑定到 ASP.NET 页面的 Web 数据控件。该语法是 ASP.NET 1.x 应用程序使用的模式,可以在 2.0 应用程序中继续使用。它通过将获得的数据集赋值给Web数据控件的DataSource属性,然后调用DataBind()方法来显示数据。并且, ASP.NET 2.0 新的数据源控件提供了新的声明方式来处理数据。使用这些控件,无需编写一行代码就可以绑定通过前面教程 创建的 BLL 检索出的数据。

ASP.NET 2.0 附带有五个内置数据源控件 – SqlDataSourceAccessDataSourceObjectDataSourceXmlDataSourceSiteMapDataSource ,但是,如果需要,用户仍然可以自己构建自定义数据源控件 。由于我们已经为教程应用程序开发了一个体系结构,因此我们将基于现有的 BLL 类来使用 ObjectDataSource 。

图1 :ASP.NET 2.0 包含五个内置数据源控件

ObjectDataSource 充当协调其他对象的代理。要配置 ObjectDataSource , 需要指定这个底层对象 , 需要指定该对象的方法如何映射到 ObjectDataSource 的 Select 、Insert 、Update 和 Delete 方法。一旦指定了底层对象,并且该对象的方法也映射到了 ObjectDataSource 的对象,就可以将 ObjectDataSource 绑定到 Web 数据控件了。 ASP.NET 附带了许多 Web 数据控件,其中包括 GridView 、 DetailsView 、 RadioButtonList 和 DropDownList 。在页面的整个生命周期中,Web 数据控件可能需要访问它绑定的数据,这是通过调用它的 ObjectDataSource 的 Select 方法实现的;如果 Web 数据控件支持插入、更新或删除,将执行对控件的 ObjectDataSource 的 Insert 、 Update 或 Delete 方法的调用。接着,通过 ObjectDataSource 将这些调用发送到相应底层对象的方法,如下图所示。

图2 :ObjectDataSource 充当代理

了解了能够使用ObjectDataSource 调用插入、更新或删除数据的方法后,我们将关注返回数据;后续教程中将介绍使用ObjectDataSource 和 Web 数据控件修改数据。

步骤1 :添加和配置ObjectDataSource 控件

首先,打开BasicReporting 文件夹中的 SimpleDisplay.aspx 页面,切换到Design 视图,然后,将ObjectDataSource 控件从 Toolbox 拖放到页面的设计界面。在设计界面上 ObjectDataSource 显示为一个灰色框,这是因为它还没有产生任何标记;通过调用来自指定对象的一个方法可以简单地访问数据。通过 Web 数据控件(例如 GridView 、 DetailsView 、 FormView 等)可以显示由 ObjectDataSource 返回的数据。

注意:或者,也可以先向页面添加 Web 数据控件,然后从它的智能标记的 下拉列表 选择 <New data source> 选项。

要指定 ObjectDataSource 的底层对象以及该对象的方法如何映射到ObjectDataSource 的对象,从ObjectDataSource 的智能标记单击 Configure Data Source 链接。

图3 :从智能标记单击 Configure Data Source 链接

这将启动Configure Data Source 向导。首先,必须首先指定与 ObjectDataSource 绑定的对象。如果 "Show only data components" 复选框选中,则该屏幕的下拉列表中只列出具有 DataObject 属性的那些对象。当前列表包括 Typed DataSet 的 TableAdapters 和前面教程中创建的 BLL 类。如果之前忘记向业务逻辑层类添加 DataObject 属性,则在列表看不到这些类。 这种情况下,取消对 "Show only data components" 复选框的选中以便查看所有对象,这时将显示 BLL 类(以及 Typed DataSet 的其他类,如 DataTables 、 DataRows 等)。

在第一个屏幕中,从下拉列表选择 ProductsBLL 类,然后单击 Next 。

图4 : 指定 绑定到ObjectDataSource 控件的对象

向导的下个屏幕提示用户选择 ObjectDataSource 应调用的方法。下拉列表列出了上个屏幕所选对象中返回数据的所有方法。在此,看到GetProductByProductID 、GetProducts 、GetProductsByCategoryID 和GetProductsBySupplierID 。从下拉列表中选择 GetProducts 方法,然后单击 Finish (如果像前面教程中显示的,向 ProductBLL 的方法添加了 DataObjectMethodAttribute ,则默认选中该选项)。

图5 :从 SELECT 选项卡选择Method for Returning Data

人工配置ObjectDataSource

Configure Data Source 向导为我们配置ObjectDataSource 提供了一个便捷的方式,通过该向导指定 ObjectDataSource 使用的对象,并且关联到对象所调用的方法。并且,还可以通过 ObjectDataSourc 的属性、或者通过 Properties 窗口或直接使用声明标记来配置 ObjectDataSource 。简单地将 TypeName 属性设置为所使用的底层对象的类型,将 SelectMethod 设置为检索数据时调用的方法。

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

尽管你可能更喜欢使用Configure Data Source 向导,但有时你还是需要手工配置ObjectDataSource ,因为向导只列出了开发者创建的类。如果想要将ObjectDataSource 绑定到 .NET Framework 中的类( 如 : 要访问用户帐户信息 ,需要 绑定到Membership 类 ;或者要处理文件系统信息,需要绑定到Directory 类 ),则需要手工设置ObjectDataSource 的 属性。

步骤2 :添加Web 数据控件并将其绑定到ObjectDataSource

一旦向页面添加了 ObjectDataSource 并且已经进行了配置,就可以向该页面添加 Web 数据控件以显示由 ObjectDataSource 的 Select 方法返回的数据。你可以将任何 Web 数据控件绑定到 ObjectDataSource ;这里我们介绍用 GridView 、 DetailsView 和 FormView 显示 ObjectDataSource 数据。

将 GridView 绑定到ObjectDataSource

从Toolbox 向 SimpleDisplay.aspx 的设计界面添加 GridView 控件。从 GridView 的智能标记,选择步骤1 中添加的 ObjectDataSource 控件。这将自动的在GridView中为数据的每个属性( 即,由Products DataTable 定义的属性 ) 创建BoundField ,而这些数据是由ObjectDataSource 的Select 方法所返回的 。

图6 :GridView 已经添加到页面,并且已经绑定到ObjectDataSource

用户可以单击智能标记的 Edit Columns 选项来定制、重新排列或删除 GridView 的BoundFields 。

图7 :通过 Edit Columns 对话框来管理 GridView 的BoundField

需要一些时间来修改 GridView 的 BoundField , 删除ProductID 、SupplierID 、CategoryID 、QuantityPerUnit 、UnitsInStock 、UnitsOnOrder 和 ReorderLevel BoundField 。简单地从左下角列表中选择 BoundField 并单击删除按钮(红色 X )来删除它们。接着,通过选择这些 BoundField 并单击向上箭头来重新排列这些 BoundField ,使 CategoryName 和 SupplierName BoundField 排在 UnitPrice BoundField 的前面。分别将剩余的 BoundField 属性设置为 Products 、 Category 、 Supplier 和 Price 。接着,通过将 BoundField 的 HtmlEncode 属性设置为 False ,将它的 DataFormatString 设置为 {0:c} ,而将 Price BoundField 格式设为货币格式。最后,通过 ItemStyle/HorizontalAlign 属性将 Price 水平靠右对齐,将 Discontinued 复选框水平居中。

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName"
         HeaderText="Product" SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName"
          HeaderText="Category" ReadOnly="True"
          SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
          HeaderText="Supplier" ReadOnly="True"
          SortExpression="SupplierName" />
        <asp:BoundField DataField="UnitPrice"
          DataFormatString="{0:c}" HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
        <asp:CheckBoxField DataField="Discontinued"
          HeaderText="Discontinued" SortExpression="Discontinued">
            <ItemStyle HorizontalAlign="Center" />
        </asp:CheckBoxField>
    </Columns>
</asp:GridView>

图8 :已经定制了BoundField 的GridView

使用主题(Themes )保持显示风格的一致

这些教程力争避免任何控件级的样式设置,尽可能的使用外部文件定义的级联样式表。 Styles.css 文件包含 DataWebControlStyle 、 HeaderStyle 、 RowStyle 和 AlternatingRowStyle CSS 类,使用这些类来规定这些教程中使用的 Web 数据控件的外观。要实现这一点,应该将 GridView 的 CssClass 属性设置为 DataWebControlStyle ,从而设置它的 HeaderStyle 、 RowStyle 和 AlternatingRowStyle 的 CssClass 属性。

如果在Web 控件中设置了这些 CssClass 属性,则需要记住要为添加到教程中的每个Web 控件明确设置这些属性值。一个比较便于管理的方法就是:使用 Theme 为 GridView 、 DetailsView 和 FormView 控件定义默认的 CSS 相关属性。Theme 是一组控件级的属性设置、图像和 CSS 类,这些内容可以在整个站点应用以便强制共同的外观。

我们的Theme 不包含任何图像或 CSS 文件( 我们将保持stylesheet Styles.css , 像网站应用程序根文件夹中定义的一样 ),但是将包含两个Skin 。一个Skin 为一个文件,它为Web 控件定义了默认属性。具体地说,我们将有针对 GridView 和 DetailsView 控件的Skin 文件,包括默认的 CssClass 相关属性。

首先,右键单击Solution Explore 中的项目名称,接着选择 Add New Item ,向项目添加一个名称为 GridView.skin 的新外观文件。

图9 :添加一个名称为 GridView.skin 的外观文件

需要将外观文件放置在 Theme 中,Theme 位于 App_Themes 文件夹。尽管还没有这个文件夹,但添加第一个外观文件时 Visual Studio 将自动创建该文件夹。单击 Yes 以便创建 App_Theme 文件夹,然后将新的 GridView.skin 文件放在其中。

图10 :Visual Studio 创建 App_Theme 文件夹

这将在 App_Themes 文件夹中创建名称为 GridView 的新 Theme ,它包含外观文件 GridView.skin 。

图11 :GridView Theme 已经被添加到 App_Theme 文件夹

将GridView Theme 重命名为 DataWebControls ( 在 App_Theme 文件夹中右键单击 GridView 文件夹,接着选择Rename )。接着,将下列标记输入到 GridView.skin 文件中:

<asp:GridView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />
</asp:GridView>

这就为使用DataWebControls Theme 的任何页面中的任何GridView 的 CssClass 相关属性定义了默认属性。让我们为 DetailsView 添加另一个Skin , DetailsView 是我们稍后将要使用的一个 Web 数据控件。向 DataWebControls Theme 添加名称为 DetailsView.skin 的新外观,接着添加下列标记:

<asp:DetailsView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <FieldHeaderStyle CssClass="HeaderStyle" />
</asp:DetailsView>

完成对Theme 的定义,最后一步就是将 Theme 应用于我们的 ASP.NET 页面。可以逐个页面应用 Theme ,也可以将 Theme 应用于网站中的所有页面。让我们将该 Theme 用于网站的所有页面。 要实现这一点,将下列标记添加到 Web.config 的 <system.web> 部分:

<pages styleSheetTheme="DataWebControls" />

这样就可以了!styleSheetTheme 设置表示 Theme 指定的属性将不会覆盖控件级指定的属性。要想规定让 Theme 设置取代控件级的设置,就要用 theme 属性代替 styleSheetTheme ;但是通过 theme 属性指定的 Theme 设置不显示在 Visual Studio Design 视图中。有关 Theme 和外观的详细信息,参考 ASP.NET Theme 和Skin 概述 以及Server-Side Styles Using Theme;有关配置页面以便使用 Theme 的详细信息参见如何:应用 ASP.NET Theme

图12 :GridView 显示产品的 Name 、Category 、Supplier 、Price 和 Discontinued 信息

在DetailsView中每次显示一个记录

GridView 对其绑定的数据源控件返回的每条记录均显示一行。然而,很多时候,用户每次只想单独显示一个记录。DetailsView 控件提供了这一功能,对其绑定的每一列或每个属性显示为两列一行的 HTML < table > 。可以将 DetailsView 视为带有一个记录的旋转 90 度的 GridView 。

首先,在SimpleDisplay.aspx 中,在 GridView 上添加DetailsView 控件。接着,将其与 GridView 绑定到同一个 ObjectDataSource 控件。与 GridView 一样,对 ObjectDataSource 的 Select 方法返回的对象的每个属性,都将向 DetailsView 添加一个 BoundField 。与 GridView 的唯一区别就是, DetailsView 的 BoundField 是水平排列的,而 GridView 的是垂直排列。

图13 : 将 DetailsView 添加到页面,并将其绑定到 ObjectDataSource

与GridView 一样,可以对 DetailsView 的 BoundField 进行调整,以便对ObjectDataSource 返回的数据显示进行更多的定制。图 14 显示了 DetailsView 的一个示例,这里已经对其 BoundField 和 CssClass 属性进行了配置使其外观与 GridView 类似。

图14 :DetailsView 只显示一条记录

注意:DetailsView 只显示其数据源返回的第一条记录。要使用户能每次一个地逐个显示所有记录,必须对 DetailsView 启用分页。为此,需要返回 Visual Studio ,在 DetailsView 的智能标记中选中 Enable Paging 复选框。

图15 :在 DetailsView 控件中启用分页

图16 :启用分页后,DetailsView 允许用户查看任何产品

在后续教程中我们还将进一步介绍分页。

更灵活布局每次显示的一个记录

DetailsView 在如何显示 ObjectDataSource 返回的每个记录方面是非常严格的。但是,用户也许希望显示更灵活的数据视图。例如,用户不想将产品的名称、类别、供货商、价格和折扣信息显示在一行中,而想将产品的名称和价格以 <h4> 显示为标题,类别和供货商信息以较小的字体显示在名称和价格下面。并且,也许用户不太关心显示在数值旁边的属性名称(产品、类别等)。

FormView 控件 提供了这样的定制功能。FormView 不像 GridView 和 DetailsView 使用字段,而是使用模板,它允许将Web 控件、静态 HTML 和数据绑定语法混合使用。如果您熟悉 ASP.NET 1.x 的 Repeater 控件,在显示单个记录时,您可以将 FormView 视为 Repeater 。

向SimpleDisplay.aspx 页面的设计界面添加 FormView 控件。最初,FormView 显示为灰色方块,这是在提醒用户至少要提供控件的ItemTemplate 。

图17 :FormView 必须包含 ItemTemplate

通过FormView 的智能标记可以将 FormView 直接绑定到数据源控件,这将自动创建默认 ItemTemplate ( 如果设置了ObjectDatatSource 控件的InsertMethod 和 UpdateMethod 属性,同时还将创建 EditItemTemplate 和 InsertItemTemplate )。然而,针对该示例,我们将数据绑定到 FormView ,同时手动的指定它的 ItemTemplate 。首先,将 FormView 的 DataSourceID 属性设置为 ObjectDataSource 控件的 ID ,即 ObjectDataSource1 。接着,创建 ItemTemplate ,使其以 <h4> 元素显示产品的名称和价格,在名称和价格下面以较小的字体显示产品的类别和供货商名称。

<asp:FormView ID="FormView1" runat="server"
  DataSourceID="ObjectDataSource1" EnableViewState="False">
    <ItemTemplate>
        <h4><%# Eval("ProductName") %>
          (<%# Eval("UnitPrice", "{0:c}") %>)</h4>
        Category: <%# Eval("CategoryName") %>;
        Supplier: <%# Eval("SupplierName") %>
    </ItemTemplate>
</asp:FormView>

图18 : 第一个产品 (Chai) 以自定义格式显示

<%# Eval(propertyName) %> 为数据绑定语法。Eval 方法返回当前绑定到 FormView 控件的对象的指定属性的值。有关数据绑定的详细信息,参考 Alex Homer 的文章ASP.NET 2.0 的基本和扩展的数据绑定语法

像DetailsView 一样,FormView 也只显示 ObjectDataSource 返回的第一个记录。可以在 FormView 中启用分页,以便允许访问者每次一个地逐个查看产品。

小结

利用ASP.NET 2.0 的 ObjectDataSource 控件,无需编写一行代码即可实现对来自业务逻辑层数据的访问和显示。 ObjectDataSource 调用一个指定的类方法,并返回结果。这些结果显示在绑定到 ObjectDataSource 的 Web 数据控件中。通过本教程,我们了解了绑定到 ObjectDataSource 的 GridView 、 DetailsView 和 FormView 控件。

目前为止,我们仅对如何使用 ObjectDataSource 调用无参数方法进行了了解,但是,我们该如何调用含有输入参数的方法( 如 ProductBLL 类的GetProductsByCategoryID(categoryID) )呢?为了调用含有一个或多个参数的方法,必须对 ObjectDataSource 进行配置,为这些参数指定参数值。在下一教程中,我们将了解怎样实现这一功能。

快乐编程!





下一篇教程