基于数据自定义格式

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

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

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

Part 2

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

完成FormView 的标记后,下一步是通过编程确定 UnitsInStock 的值是否小于或等于10 。 FormView 的操作方法与 DetailsView 的操作方法完全相同。首先为 FormView 的 DataBound 事件创建一个 Event Handler。

图6 :创建 DataBound Event Handler

在Event Handler 中,将 FormView 的 DataItem 属性转换为 ProductsRow 实例,并确定是否要将 UnitsInPrice 值显示为红色字体。

protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)LowStockedProductsInRed.DataItem).Row;
    if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)
    {
        // TODO: Make the UnitsInStockLabel text red
    }
}

步骤6:在 FormView 的 ItemTemplate 中设置 UnitsInStockLabel Label 控件的格式

最后一步是将显示的 UnitsInStock 值( 小于等于 10 )设置为红色字体。为此,需要通过编程访问 ItemTemplate 中的 UnitsInStockLabel 控件,并设置其样式属性,使其文本显示为红色。要访问模板中的 Web 控件,需要以如下方式使用 FindControl("controlID") 方法:

WebControlType someName = (WebControlType)FormViewID.FindControl("controlID");

本例中,我们想访问一个 ID 值为 UnitsInStockLabel 的Label 控件,因此使用 :

Label unitsInStock = (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel");

一旦有了对 Web 控件的编程引用后,我们就可根据需要更改其样式相关的属性。与上个示例相同,本例在 Styles.css 中创建了一个名为 LowUnitsInStockEmphasis 的 CSS 类。要将此样式应用于 Label Web 控件,应对 CssClass 属性作相应设置。

protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)LowStockedProductsInRed.DataItem).Row;
    if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)
    {
        Label unitsInStock =
            (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel");
        if (unitsInStock != null)
        {
          unitsInStock.CssClass = "LowUnitsInStockEmphasis";
        }
    }
}

注意:在使用 DetailsView 或 GridView 控件中的TemplateFields 时,也可使用设置模板格式的语法:使用FindControl("controlID") 通过编程访问Web 控件,然后设置其样式相关的属性。我们将在下一篇教程中详细介绍 TemplateFields 。

图7 显示的是查看一个其 UnitsInStock 值大于 10 的产品 时的 FormView 。图 8 则为查看一个其 UnitsInStock 值小于 10 的产品时的 FormView

图7 :自定义格式不应用于存货量相当大的产品

图8 :存货量小于或等于 10 的产品,其存货量显示为红色

使用GridView 的RowDataBound 事件设置格式

前面我们详细介绍了对 DetailsView 和 FormView 控件进行数据绑定的步骤。现在再次对这些步骤作一回顾。

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

由于DetailsView 和 FormView 只显示一个记录,所以使用这三个简单步骤就足够了。对于 GridView 而言,由于它显示的是与它绑定的所有记录(而不只是第一个),步骤 2 就稍微复杂一些。

在步骤2 中,GridView 列出了数据源,并为每个记录都创建一个GridViewRow 实例并将当前记录绑定到该实例。对于每个添加到 GridView 的 GridViewRow ,都会触发两个事件:

  • RowCreated:在创建 GridViewRow 后触发;
  • RowDataBound:在当前记录被绑定到 GridViewRow 后触发。

那么,就 GridView 而言,以下步骤对数据绑定描述得更准确 :

  1. GridView 的 DataBinding 事件触发。
  2. 数据被绑定到 GridView 。
    对数据源中的每个记录:
    1. 创建一个 GridViewRow 对象;
    2. 触发 RowCreated 事件;
    3. 将记录绑定到 GridViewRow ;
    4. 触发 RowDataBound 事件;
    5. 将 GridViewRow 添加到 Rows 集合。
  3. 触发 GridView 的 DataBound 事件。

然后,要自定义GridView 中单个记录的格式,我们需要为 RowDataBound 事件创建一个 Event Handler 。作为演示,我们将向 CustomColors.aspx 页面添加一个 GridView ,列出每件产品的名称、类别和价格。价格低于 $10.00 的产品将以黄色背景突出显示。

步骤7 :在 GridView 中显示产品信息

在上个示例中的 FormView 下方添加一个 GridView , 并将其ID 属性赋值为HighlightCheapProducts 。由于我们已经有一个返回页面上所有产品的 ObjectDataSource ,将 GridView 绑定到该 ObjectDataSource 。最后,编辑 GridView 的 BoundFields ,使其仅包含产品的名称、类别和价格。这些编辑完成后, GridView 的标记应如下所示:

<asp:GridView ID="HighlightCheapProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
          SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category"
          ReadOnly="True" SortExpression="CategoryName" />
        <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
          HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>

图9 显示的是通过浏览器看到的目前的操作进度。

图9 :GridView 列出每件产品的名称、类别和价格

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

ProductsDataTable 被绑定到 GridView 时,其 ProductsRow 实例将被列举,并为每个 ProductsRow 创建一个 GridViewRow 。 GridViewRow 的 DataItem 属性被指定到特定的 ProductRow ,然后 GridView 的 RowDataBound Event Handler 被触发。然后,我们需要为 GridView 的 RowDataBound 事件创建一个 Event Handler,以确定绑定到 GridView 的每件产品的 UnitPrice 值。在此 Event Handler 中,可以查看当前 GridViewRow 的 UnitPrice 值,并确定该行的格式。

此 Event Handler 可以用与 FormView 和 DetailsView 一样的步骤来创建。

图10 :为 GridView 的 RowDataBound 事件创建一个 Event Handler

以这种方式创建Event Handler 将会自动向 ASP.NET 页面的代码部分添加如下代码 :

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
}

触发 RowDataBound 事件时,这个EventHandler 的第二个参数被传入,这个参数是一个GridViewRowEventArgs类型的对象,该对象有个属性为Row 。此属性返回一个刚刚绑定的 GridViewRow 的引用。访问绑定到 GridViewRow 的 ProductsRow 实例,我们需要使用 DataItem 属性,如下所示:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((System.Data.DataRowView)e.Row.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
    {
        // TODO: Highlight the row yellow...
    }
}

操作RowDataBound Event Handler 时,重要的是 要记住 GridView 包含多个类型的行,而此 Event Handler 对于所有行类型都是可触发的。 GridViewRow 的类型可以通过其 RowType 属性确定,其值可为如下某种:

  • DataRow :绑定到 GridView 的 DataSource 的某条记录的行;
  • EmptyDataRow :当 GridView 的 DataSource 为空时显示的行;
  • Footer :脚注行,在 GridView 的 ShowFooter 属性被赋值为 true 时显示;
  • Header :标题行,在 GridView 的 ShowHeader 属性被赋值为 true ( 默认值 )时显示;
  • Pager :针对实现分页的 GridView ,为显示分页界面的行;
  • Separator :不用于 GridView ,但被 RowType 属性用于 DataList 和 Repeater 控件,我们将在后面教程中介绍这两个 Web 数据 控件。

由于 EmptyDataRow 、Header 、Footer 和 Pager 行不与 DataSource 记录相关联,他们始终将 null 赋值给其 DataItem 属性。因此,在准备操作当前 GridViewRow 的 DataItem 属性之前,必须首先确保操作的是 DataRow 。这可以通过查看 GridViewRow 的 RowType 属性来实现,如下所示:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Make sure we are working with a DataRow
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Get the ProductsRow object from the DataItem property...
        Northwind.ProductsRow product = (Northwind.ProductsRow)
            ((System.Data.DataRowView)e.Row.DataItem).Row;
        if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
        {
          // TODO: Highlight row yellow...
        }
    }
}

步骤 9:用黄色突出显示小于 $10.00 的 UnitPrice 值

最后一步是通过编程突出显示 UnitPrice 值小于 $10.00 的整个 GridViewRow 。访问 GridView 中的行或单元格的语法与 DetailsView 相同,即用 GridViewID.Rows[index] 访问整行,用 GridViewID.Rows[index].Cells[index] 访问特定单元格。但是,当 RowDataBound Event Handler 触发数据绑定时,还需要为 GridView 的 Rows 集合添加 GridViewRow 。因此,不能使用 Rows 集合在 RowDataBound Event Handler 中访问当前 GridViewRow 实例。

我们可以使用 e.Row ,而不是 GridViewID.Rows[index] ,在 RowDataBound Event Handler 中引用当前 GridViewRow 实例。也就是说,要从 RowDataBound Event Handler 中突出显示当前 GridViewRow 实例,应使用:

e.Row.BackColor = System.Drawing.Color.Yellow;

我们将不直接设置 GridViewRow 的 BackColor 属性,而是仍然使用 CSS 类。我已经创建了一个名为AffordablePriceEmphasis 的CSS 类,并将背景设为黄色。完成的 RowDataBound Event Handler 如下所示 :

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Make sure we are working with a DataRow
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Get the ProductsRow object from the DataItem property...
        Northwind.ProductsRow product = (Northwind.ProductsRow)
            ((System.Data.DataRowView)e.Row.DataItem).Row;
        if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
        {
            e.Row.CssClass = "AffordablePriceEmphasis";
        }
    }
}

图11 :价格低廉的产品以黄色突出显示

小结

本教程中,我们介绍了如何基于绑定到 GridView 、DetailsView 和FormView 控件的数据设置这些控件的格式。操作方法是:为 DataBound 或 RowDataBound 事件创建一个 Event Handler,用来查看底层数据并在需要时进行格式更改。要访问绑定到 DetailsView 或 FormView 的数据,在 DataBound Event Handler 中要使用 DataItem 属性。对于 GridView ,每个 GridViewRow 实例的 DataItem 属性包含绑定到该行的数据,这些数据在 RowDataBound Event Handler 中是可用的。

通过编程调整Web 数据 控件格式的语法取决于 Web 控件和要设置格式的数据的显示方式。 DetailsView 和 GridView 控件的行和单元格可以用一个顺序索引访问。由于FormView 使用模板,因此常使用 FindControl("controlID") 方法在模板中定位 Web 控件。

我们在下一篇教程中将介绍如何在 GridView 和 DetailsView 中使用模板。此外,还将介绍根据底层数据自定义格式的另一种方法。

快乐编程 !





上一页 | 1 | 2 | 下一页

下一篇教程