基于数据自定义格式

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

可以用多种方式实现根据绑定的数据对 GridView、DetailsView 或 FormView 的格式的调整。本教程中,我们将说明如何通过使用 DataBound 和 RowDataBound Event Handler 来完成数据绑定格式化。

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

Part 1

简介

通过多种与样式相关的属性,可以自定义GridView 、DetailsView 和FormView 控件的外观。 CssClass 、Font 、BorderWidth 、BorderStyle 、BorderColor 、Width 和 Height 是决定所显示控件整体外观的属性。 HeaderStyle 、RowStyle 、AlternatingRowStyle 及其他属性则用于为特定区域应用相同的样式设置。这些样式设置同样可应用于字段级别。

但在很多场景中,格式化要求根据所显示数据的值有所不同。例如,若要突出显示脱销产品,可以将产品信息列表中 UnitsInStock 和 UnitsOnOrder 字段都为 0 的产品背景设为黄色。要突出显示价格较高的产品,可将价格在 $75.00 以上的产品以粗体字显示。

可以用多种方式实现基于数据绑定对 GridView 、DetailsView 或FormView 的格式的调整。本教程中,我们将说明如何通过使用 DataBound 和 RowDataBound Event Handler 来完成数据绑定格式化。下一本教程中将探讨另一种方法。

使用 DetailsView 控件的DataBoundEvent Handler

数据被绑定到DetailsView 时,从数据源控件或通过编程将数据指定到控件的DataSource 属性并调用其 DataBind() 方法。步骤如下 :

  1. Web 数据控件的 DataBinding 事件触发。
  2. 该数据被绑定到 Web 数据控件。
  3. Web 数据控件的 DataBound 事件触发。

上述步骤 1 -3 完成后,可以通过 Event Handler 立即注入自定义逻辑。通过为 DataBound 事件创建一个 Event Handler ,我们可通过编程指定要绑定到 Web 数据控件的数据并根据需要调整格式。作为演示,下面我们将创建一个 DetailsView 列出关于某件产品的常用信息,但将其 UnitPrice 值显示为加粗字体,如果其价格超过 $75.00 则显示为加粗斜体

步骤1 :在 DetailsView 中显示产品信息

打开CustomFormatting 文件夹中的CustomColors.aspx 页面,从 Toolbox 上拖动一个 DetailsView 控件到 Designer 中,将其 ID 属性值赋值为 ExpensiveProductsPriceInBoldItalic 并将其绑定到一个新的 ObjectDataSource 控件,该控件调用 ProductsBLL 类的GetProducts() 方法。由于前面的教程中已经讲解过上述操作,因此这里省略其详细步骤不提。

将ObjectDataSource 绑定到 DetailsView 后,花点时间来更改字段列表。这里我选择了移除ProductID 、SupplierID 、CategoryID 、UnitsInStock 、UnitsOnOrder 、ReorderLevel 和 Discontinued BoundFields ,并对其余的 BoundField 进行重命名和重新格式化操作。此外,我还清除了 Width 和 Height 设置。由于 DetailsView 只显示一条记录,我们需要启用分页功能以便终端用户能查看所有产品。操作方法为勾选上 DetailsView 的智能标记中的 Enable Paging 复选框。

图1 :勾选上 DetailsView 的智能标记中的 Enable Paging 复选框

完成上述更改后,DetailsView 标记将如下所示:

<asp:DetailsView ID="DetailsView1" runat="server" AllowPaging="True"
    AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Fields>
        <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="QuantityPerUnit"
          HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
          HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice" />
    </Fields>
</asp:DetailsView>

花点时间在浏览器中测试一下该页面。

图2 :DetailsView 控件一次显示一种产品

步骤2 :在 DataBound Event Handler 中通过编程确定数据的值

要用加粗斜体字显示其 UnitPrice 值超过 $75.00 的产品价格,我们需要首先能通过编程确定该UnitPrice 值。在 DetailsView 中,这一操作通过 DataBound Event Handler 来完成。要创建 Event Handler,单击 Designer 中的 DetailsView ,然后进入 Properties 窗口。若 Properties 窗口未打开,需要按下 F4 使其显示,或选择 View 菜单上的 Properties Window 菜单选项。单击 Properties 窗口中的闪电图标列出 DetailsView 的事件。然后双击 DataBound 事件或键入要创建的 Event Handler 的名称。

图3 :为 DataBound 事件创建 Event Handler

这将自动创建一个Event Handler 并进入其被添加的代码部分。此时,可看到如下代码:

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{
}

通过DataItem 属性可访问绑定到 DetailsView 的数据。记住,我们正在将控件绑定到强类型的 DataTable ,DataTable 包含一个强类型的 DataRow 实例集。当 DataTable 被绑定到 DetailsView 时, DataTable 中的第一个 DataRow 被指定为 DetailsView 的 DataItem 属性。具体地说, DataItem 属性被指定到一个 DataRowView 对象。我们可以使用 DataRowView 的 Row 属性来访问底层的 DataRow 对象,该对象实际上是一个 ProductsRow 实例。一旦有了这个 ProductsRow 实例,我们就可以通过简单查看该对象的属性值来作出决定。

下列代码演示了如何判断绑定到DetailsView 控件的UnitPrice 值是否大于$75.00 :

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)ExpensiveProductsPriceInBoldItalic.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice > 75m)
    {
        // TODO: Make the UnitPrice text bold and italic
    }
}

注意:由于 UnitPrice 在数据库中的值可以为 NULL ,所以 我们要在访问 ProductsRow 的 UnitPrice 属性 之前首先查看,以确认操作的不是 NULL 值。此检查非常重要,因为如果试图访问值为 NULL 的 UnitPrice 属性,ProductsRow 对象将抛出一个 StrongTypingException 异常

步骤3 :设置 DetailsView 中的 UnitPrice 值

现在我们能够确定绑定到 DetailsView 的 UnitPrice 值是否超过 $75.00 ,但还要学习如何据此通过编程调整 DetailsView 的格式。要更改 DetailsView 中某行的格式,使用 DetailsViewID.Rows[index] 通过编程访问该行;要更改某单元格,使用DetailsViewID.Rows[index].Cells[index] 。一旦有了对行或单元格的引用后,接下来便可通过设置其与样式相关的属性来调整其外观了。

要通过编程访问某行,需要知道该行的索引。索引从 0 开始。UnitPrice 行是 DetailsView 的第 5 行,因此应使用其索引 4 ,并使用 ExpensiveProductsPriceInBoldItalic.Rows[4] 使其通过编程访问。现在我们可以使用以下代码,使此行所有内容显示为加粗斜体字:

ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Bold = true;
ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Italic = true;

但这将使标签 (Price) 和值都显示为加粗斜体。如果只希望值显示为加粗斜体,需要将此格式应用到行中的第二个单元格,相应代码如下:

ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].Font.Bold = true;
ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].Font.Italic = true;

由于到目前为止的教程都使用样式表来严格区分显示的标记和样式相关的信息,而不是象前面所示那样设置具体的样式属性。我们接下来将使用一个 CSS 类。打开 Styles.css 样式表,新增一个名为 ExpensivePriceEmphasis 的 CSS 类,带有如下定义:

.ExpensivePriceEmphasis
{
    font-weight: bold;
    font-style: italic;
}

然后在 DataBound Event Handler 中将单元格的CssClass 属性赋值为 ExpensivePriceEmphasis。下列代码完整显示了 DataBound Event Handler:

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)ExpensiveProductsPriceInBoldItalic.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice > 75m)
    {
        ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].CssClass =
            "ExpensivePriceEmphasis";
    }
}

查看Chai 时,由于其价格低于 $75.00 ,因此以常规字体显示( 见图4 )。但是在查看 Mishi Kobe Niku 时,由于其价格为 $97.00 ,因此显示为加粗斜体(见图 5 )。

图4 :价格低于 $75.00 的以常规字体显示

图5 :较贵的产品价格显示为加粗斜体

使用 FormView 控件的DataBoundEvent Handler

确定绑定到FormView 的底层数据的步骤与确定绑定到 DetailsView 的底层数据的步骤相同:创建一个DataBound Event Handler ,将 DataItem 属性转换为绑定到控件的相应对象,并确定处理方式。但 FormView 和 DetailsView 在如何更新其用户界面的外观上有所不同。

FormView 不包含任何 BoundFields ,因此没有 Rows 集合。而 FormView 由模板组成,模板中可包含静态 HTML 、Web 控件和数据绑定语法。调整 FormView 样式通常涉及到调整 FormView 模板中一个或多个 Web 控件。

作为演示,我们将使用一个 FormView 列出产品,与上个示例一样,但这次是只显示产品名称及其存货数量,小于或等于10 的存货数量将显示为红色字体。

步骤4:在 FormView 中显示产品信息

向CustomColors.aspx 页面的 DetailsView 下方添加一个 FormView ,并将其 ID 属性赋值为 LowStockedProductsInRed 。将 FormView 绑定到上个步骤中创建的 ObjectDataSource 控件。这将为 FormView 创建一个 ItemTemplate 、 EditItemTemplate 和 InsertItemTemplate 。移除 EditItemTemplate 和 InsertItemTemplate ,简化 ItemTemplate 使其仅包含 ProductName 和 UnitsInStock 值,这两个值都位于各自被命名的 Label 控件中。与上例中的 DetailsView 相同,也勾选上 FormView 的智能标记中的 Enable Paging 复选框。

完成上述编辑后,FormView 的标记应如下所示:

<asp:FormView ID="LowStockedProductsInRed" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True"
    EnableViewState="False" runat="server">
    <ItemTemplate>
        <b>Product:</b>
        <asp:Label ID="ProductNameLabel" runat="server"
         Text='<%# Bind("ProductName") %>'>
        </asp:Label><br />
        <b>Units In Stock:</b>
        <asp:Label ID="UnitsInStockLabel" runat="server"
          Text='<%# Bind("UnitsInStock") %>'>
        </asp:Label>
    </ItemTemplate>
</asp:FormView>

注意,ItemTemplate 包含:

  • 静态HTML:文本 “Product: ” 和 “Units In Stock: ” 以及<br /> 与 <b> 元素。
  • Web控件:两个Label 控件:ProductNameLabel 和 UnitsInStockLabel 。
  • 数据绑定语法:<%# Bind("ProductName") %> 和<%# Bind("UnitsInStock") %> 语法,将这些字段的值指定到Label 控件的 Text 属性。




上一页 | 1 | 2 | 下一页