根據資料格式化 DataList 和重複項 (VB)

作者:Scott Mitchell

下載 PDF

在本教學課程中,我們將逐步解說如何格式化 DataList 和 Repeater 控件的外觀範例,方法是使用範本內的格式化函式或處理 DataBound 事件。

簡介

如上一個教學課程中所見,DataList 提供一些會影響其外觀的樣式相關屬性。 特別是,我們已瞭解如何將預設 CSS 類別指派給 DataList s HeaderStyleItemStyleAlternatingItemStyleSelectedItemStyle 屬性。 除了這四個屬性之外,DataList 還包含一些其他樣式相關屬性,例如 FontForeColorBackColorBorderWidth,以命名為一些。 Repeater 控制件不包含任何樣式相關的屬性。 任何這類樣式設定都必須直接在重複項範本中的標記內進行。

不過,數據的格式通常取決於數據本身。 例如,當列出產品時,如果產品已停止,我們可能會想要以淺灰色字型色彩顯示產品資訊,或者如果值為零,我們可能會想要反 UnitsInStock 白顯示該值。 如先前教學課程中所見,GridView、DetailsView 和 FormView 提供兩種不同的方式,根據數據格式化其外觀:

  • 事件DataBound會針對適當的DataBound事件建立事件處理程式,此事件處理程式會在數據系結至 GridView RowDataBound 的每個專案 (之後引發;如果是 DataList 和 Repeater,則為ItemDataBound事件) 。 在該事件處理程式中,您可以檢查資料並設定設定格式決策。 我們已在 自定義格式化根據數據 教學課程中檢查這項技術。
  • DetailsView 或 GridView 控件中使用 TemplateFields 或 FormView 控件中的範本時,我們可以將格式化函式新增至 ASP.NET 頁面程式代碼後置類別、商業規則層,或可從 Web 應用程式存取的任何其他類別庫。 此格式設定函式可以接受任意數目的輸入參數,但必須傳回 HTML 才能在範本中呈現。 第一次在 GridView 控制項中使用 TemplateFields 教學課程中檢查格式化函式。

這兩種格式化技術都可搭配 DataList 和 Repeater 控件使用。 在本教學課程中,我們將逐步解說這兩種控件使用兩種技巧的範例。

ItemDataBound使用事件處理程式

當數據系結至 DataList 時,請從數據源控件,或透過以程式設計方式將數據指派給控件 s DataSource 屬性,並呼叫其 DataBind() 方法時,DataList s DataBinding 事件會引發、列舉數據源,以及每個數據記錄都會系結至 DataList。 針對數據源中的每個記錄,DataList 會 DataListItem 建立對象,然後系結至目前的記錄。 在此程式中,DataList 會引發兩個事件:

  • ItemCreated 建立 之後 DataListItem 引發
  • ItemDataBound 在目前記錄系結至 之後引發 DataListItem

下列步驟概述 DataList 控件的數據系結程式。

  1. DataList 事件DataBinding會引發

  2. 數據系結至 DataList

    針對數據源中的每個記錄

    1. 建立 DataListItem 物件
    2. ItemCreated引發事件
    3. 將記錄系結至 DataListItem
    4. ItemDataBound引發事件
    5. DataListItem將加入至Items集合

將數據系結至 Repeater 控制項時,它會逐步執行完全相同的步驟序列。 唯一的差別在於,重複程式會使用 RepeaterItem,而不是DataListItem建立的實例。

注意

astute 讀取器可能會注意到DataList和Repeater系結至數據時,與 GridView 系結至數據時,步驟序列之間的稍微異常。 在數據系結程序的結尾,GridView 會引發 DataBound 事件;不過,DataList 或 Repeater 控件都沒有這類事件。 這是因為 DataList 和 Repeater 控制件是在 ASP.NET 1.x 時間範圍中建立的,在前置和後置事件處理程式模式變得常見之前。

如同 GridView,根據數據格式化的其中一個選項是建立事件的事件處理程式 ItemDataBound 。 此事件處理程式會檢查剛系結至 DataListItemRepeaterItem 的數據,並視需要影響控件的格式。

針對 DataList 控件,可以使用樣式相關的屬性來實DataListItem作整個專案的格式化變更,其中包括標準 FontForeColor、、 BackColorCssClass等等。 為了影響 DataList 範本內特定 Web 控件的格式設定,我們需要以程式設計方式存取和修改這些 Web 控制項的樣式。 我們已瞭解如何在 以數據為基礎的自定義格式 設定教學課程中完成此作業。 如同 Repeater 控制項,類別 RepeaterItem 沒有與樣式相關的屬性;因此,在事件處理程式中所做的 RepeaterItem 所有樣式相關變更都必須透過以程式設計方式存取及更新範本內的 ItemDataBound Web 控制項來完成。

ItemDataBound由於 DataList 和 Repeater 的格式設定技術幾乎完全相同,因此我們的範例將著重於使用 DataList。

步驟 1:在 DataList 中顯示產品資訊

在擔心格式設定之前,讓我們先建立使用 DataList 來顯示產品資訊的頁面。 在上一個 教學課程 中,我們建立了一個 DataList,其中 ItemTemplate 顯示每個產品名稱、類別、供應商、每個單位的數量,以及價格。 讓我們在此教學課程中重複這項功能。 若要達成此目的,您可以從頭開始重新建立DataList及其 ObjectDataSource,或從上一個教學課程中建立的頁面複製這些控件, Basics.aspx () ,並將其貼到本教學課程的頁面 (Formatting.aspx) 。

將 DataList 和 ObjectDataSource 功能從 Basics.aspx 複寫到 Formatting.aspx之後,請花點時間將 DataList 的 ID 屬性從 DataList1 變更為更具描述性的 ItemDataBoundFormattingExample。 接下來,在瀏覽器中檢視 DataList。 如圖 1 所示,每個產品之間的唯一格式差異是背景色彩替代。

產品列在 DataList 控件中

圖 1:產品列在 DataList 控件中, (按兩下即可檢視完整大小的影像)

在本教學課程中,讓我們格式化 DataList,讓任何價格小於 $20.00 的產品都會以黃色醒目提示其名稱和單價。

步驟 2:以程式設計方式判斷 ItemDataBound 事件處理程式中的數據值

由於只有價格低於 $20.00 的產品才會套用自定義格式,因此我們必須能夠判斷每個產品的價格。 將數據系結至 DataList 時,DataList 會列舉其數據源中的記錄,並針對每個記錄建立 DataListItem 實例,將數據源記錄系結至 DataListItem。 將特定記錄的數據系結至目前 DataListItem 對象之後,就會引發DataList s ItemDataBound 事件。 我們可以為此事件建立事件處理程式,以檢查目前 DataListItem 的數據值,並根據這些值,進行任何必要的格式變更。

建立 ItemDataBound DataList 的事件,並新增下列程式代碼:

Protected Sub ItemDataBoundFormattingExample_ItemDataBound _
    (sender As Object, e As DataListItemEventArgs) _
    Handles ItemDataBoundFormattingExample.ItemDataBound
    If e.Item.ItemType = ListItemType.Item OrElse _
       e.Item.ItemType = ListItemType.AlternatingItem Then
        ' Programmatically reference the ProductsRow instance
        ' bound to this DataListItem
        Dim product As Northwind.ProductsRow = _
            CType(CType(e.Item.DataItem, System.Data.DataRowView).Row, _
                Northwind.ProductsRow)
        ' See if the UnitPrice is not NULL and less than $20.00
        If Not product.IsUnitPriceNull() AndAlso product.UnitPrice < 20 Then
            ' TODO: Highlight the product's name and price
        End If
    End If
End Sub

雖然 DataList ItemDataBound 事件處理程式背後的概念和語意與 GridView RowDataBound 事件處理程式在 自定義格式依據數據 教學課程中使用的概念和語意相同,語法會稍有不同。 ItemDataBound當事件引發時,DataListItem只會透過 e.Item (傳遞至數據的對應事件處理程式,而不是 e.Row,如同 GridView 的RowDataBound事件處理程式) 一樣。 DataList 的 ItemDataBound 事件處理程式會針對新增至 DataList 的每個 數據列引發,包括頁首數據列、頁尾數據列和分隔符數據列。 不過,產品資訊只會系結至數據列。 因此,使用 ItemDataBound 事件來檢查系結至 DataList 的數據時,我們必須先確定我們使用數據項。 這可以藉由檢查 DataListItem s ItemType 屬性來完成,這可以有 下列八個值之一:

  • AlternatingItem
  • EditItem
  • Footer
  • Header
  • Item
  • Pager
  • SelectedItem
  • Separator

ItemAlternatingItem``DataListItem 都會讓 DataList 的數據項產生。 假設我們使用 ItemAlternatingItem,我們會存取系結至目前 DataListItem的實際ProductsRow實例。 DataListItem s DataItem 屬性包含 對象的DataRowView參考,其 Row 屬性會提供實際ProductsRow對象的參考。

接下來,我們會檢查 ProductsRow 實例的 UnitPrice 屬性。 由於 Products 資料表字段 UnitPrice 允許 NULL 值,因此在嘗試存取 UnitPrice 屬性之前,我們必須先檢查它 NULL 是否有使用 IsUnitPriceNull() 方法的值。 UnitPrice如果值不是 NULL,我們會檢查其是否小於 $20.00。 如果它確實低於 $20.00,則我們需要套用自定義格式設定。

步驟 3:醒目提示產品名稱和價格

一旦我們知道產品的價格小於 $20.00,所有仍會強調其名稱和價格。 若要達成此目的,我們必須先以程式設計方式參考 中顯示產品名稱和價格的標籤 ItemTemplate 控制件。 接下來,我們必須讓它們顯示黃色背景。 您可以直接修改標籤 BackColor 屬性 (LabelID.BackColor = Color.Yellow) 來套用此格式設定資訊;在理想情況下,所有顯示相關的事項都應該透過串聯樣式表單來表示。 事實上,我們已經有一個樣式表單,提供 中定義的所需格式,該格式設定是在 自定義格式根據數據教學課程中Styles.css - AffordablePriceEmphasis建立和討論。

若要套用格式設定,只要將兩個 Label Web 控件 CssClass 屬性設定為 AffordablePriceEmphasis,如下列程式代碼所示:

' Highlight the product name and unit price Labels
' First, get a reference to the two Label Web controls
Dim ProductNameLabel As Label = CType(e.Item.FindControl("ProductNameLabel"), Label)
Dim UnitPriceLabel As Label = CType(e.Item.FindControl("UnitPriceLabel"), Label)
' Next, set their CssClass properties
If ProductNameLabel IsNot Nothing Then
    ProductNameLabel.CssClass = "AffordablePriceEmphasis"
End If
If UnitPriceLabel IsNot Nothing Then
    UnitPriceLabel.CssClass = "AffordablePriceEmphasis"
End If

完成事件處理程序之後 ItemDataBound ,請重新瀏覽 Formatting.aspx 瀏覽器中的頁面。 如圖 2 所示,價格低於 $20.00 的產品會同時醒目提示其名稱和價格。

那些小於 $20.00 的產品會反白顯示

圖 2:[ 點選] 以檢視大小完整的影像) 醒目 (提示小於 $20.00 的產品

注意

由於 DataList 會轉譯為 HTML <table>,因此其 DataListItem 實例具有樣式相關的屬性,可設定為將特定樣式套用至整個專案。 例如,如果我們想要在價格小於 $20.00 時反白顯示 整個 專案黃色,我們可以取代參考標籤的程式代碼,並使用下列程式代碼行來設定其 CssClass 屬性: e.Item.CssClass = "AffordablePriceEmphasis" (請參閱圖 3) 。

RepeaterItem但是,組成 Repeater 控件的 ,不提供這類樣式層級的屬性。 因此,將自定義格式套用至 Repeater 需要將樣式屬性套用至重複項範本內的 Web 控制件,就像我們在圖 2 中所做的一樣。

整個產品項目針對 $20.00 以下的產品反白顯示

圖 3:針對 $20.00 (按兩下以檢視大小完整影像 的產品,已醒目提示整個產品專案)

從範本內使用格式化函式

GridView 控件的 Using TemplateFields 教學課程中,我們已瞭解如何在 GridView TemplateField 中使用格式化函式,根據系結至 GridView 數據列的數據套用自定義格式。 格式化函式是從範本叫用的方法,並傳回要在其位置發出的 HTML。 格式化函式可以位於 ASP.NET 頁的程式代碼後置類別中,也可以集中化為資料夾中的類別檔案 App_Code 或個別類別庫專案中。 如果您打算在多個 ASP.NET 頁面或其他 ASP.NET Web 應用程式中使用相同的格式化函式,將格式化函式移出 ASP.NET 頁的程式代碼後置類別是理想的方法。

為了示範格式化函式,讓我們讓產品資訊在已停止時包含產品名稱旁的 [DISCONTINUED] 文字。 此外,如果價格小於 $20.00 (,讓我們將價格反白顯示為黃色,如同我們在事件處理程式範例中 ItemDataBound 所做的一樣) ;如果價格是 $20.00 或更高版本,讓我們不要顯示實際價格,而是文字,請撥打價目。 圖 4 顯示已套用這些格式化規則的產品清單螢幕快照。

顯示 DataList 控件中所列產品的螢幕快照,其中的產品成本超過 $20.00 美元,以文字取代為「請撥打價格報價」。

圖 4:對於昂貴的產品,價格會以文字取代,請撥打價目報價 (按兩下即可檢視完整大小的影像)

步驟 1:建立格式化函式

在此範例中,我們需要兩個格式化函式,其中一個會顯示產品名稱以及 [DISCONTINUED]文字,如有需要,另一個則顯示反白顯示的價格,如果小於 $20.00,或文字,請呼叫價格報價。 讓我們在頁面的程式代碼後置類別 ASP.NET 中建立這些函式,並將其命名為 DisplayProductNameAndDiscontinuedStatusDisplayPrice。 這兩種方法都需要傳回 HTML 才能轉譯為字串,而且兩者都必須標示 Protected 為 (或 Public) ,才能從 ASP.NET 頁面的宣告式語法部分叫用。 這兩種方法的程序代碼如下:

Protected Function DisplayProductNameAndDiscontinuedStatus _
    (productName As String, discontinued As Boolean) As String
    ' Return just the productName if discontinued is false
    If Not discontinued Then
        Return productName
    Else
        ' otherwise, return the productName appended with the text "[DISCONTINUED]"
        Return String.Concat(productName, " [DISCONTINUED]")
    End If
End Function
Protected Function DisplayPrice(product As Northwind.ProductsRow) As String
    ' If price is less than $20.00, return the price, highlighted
    If Not product.IsUnitPriceNull() AndAlso product.UnitPrice < 20 Then
        Return String.Concat("<span class="AffordablePriceEmphasis">", _
                             product.UnitPrice.ToString("C"), "</span>")
    Else
        ' Otherwise return the text, "Please call for a price quote"
        Return "<span>Please call for a price quote</span>"
    End If
End Function

請注意,DisplayProductNameAndDiscontinuedStatus方法接受 和 discontinued 數據欄位的值productName做為純量值,而 DisplayPrice 方法接受ProductsRow實例 (,而不是unitPrice純量值) 。 任一種方法都可行;不過,如果格式化函式正使用可包含資料庫NULL值的純量值 (,例如 UnitPrice;這兩者都ProductNameDiscontinued不能允許NULL值) ,則必須特別小心處理這些純量輸入。

特別是,輸入參數的類型必須是 , Object 因為傳入值可能是 DBNull 實例,而不是預期的數據類型。 此外,必須進行檢查,以判斷傳入值是否為資料庫 NULL 值。 也就是說,如果我們想要 DisplayPrice 方法接受價格作為純量值,就必須使用下列程序代碼:

Protected Function DisplayPrice(ByVal unitPrice As Object) As String
    ' If price is less than $20.00, return the price, highlighted
    If Not Convert.IsDBNull(unitPrice) AndAlso CType(unitPrice, Decimal) < 20 Then
        Return String.Concat("<span class="AffordablePriceEmphasis">", _
            CType(unitPrice, Decimal).ToString("C"), "</span>")
    Else
        ' Otherwise return the text, "Please call for a price quote"
        Return "<span>Please call for a price quote</span>"
    End If
End Function

請注意,unitPrice輸入參數的類型Object為 ,而且條件語句已修改為確定 是否unitPriceDBNull為 。 此外,由於 unitPrice 輸入參數是以 Object傳入,因此必須轉換成十進位值。

步驟 2:從 DataList s ItemTemplate 呼叫 Formatting 函式

將格式化函式新增至我們的 ASP.NET 頁面程序代碼後置類別時,所有保留專案都是從 DataList s 叫用這些格式化函式 ItemTemplate。 若要從範本呼叫格式化函式,請將函式呼叫放在數據系結語法中:

<%# MethodName(inputParameter1, inputParameter2, ...) %>

在 DataList 中,ItemTemplateProductNameLabel標籤 Web 控制項目前會藉由指派其 Text 屬性<%# Eval("ProductName") %>的結果來顯示產品名稱。 若要讓它顯示名稱加上文字 [DISCONTINUED],如有需要,請更新宣告式語法,以便改為將 屬性指派 Text 給 方法的值 DisplayProductNameAndDiscontinuedStatus 。 這樣做時,我們必須使用 Eval("columnName") 語法傳入產品名稱和已停止的值。 Eval 會傳回 類型的 Object值,但 DisplayProductNameAndDiscontinuedStatus 方法需要 型 String 別和 Boolean的輸入參數;因此,我們必須將 Eval 方法傳回的值轉換成預期的輸入參數類型,如下所示:

<h4>
    <asp:Label ID="ProductNameLabel" runat="server"
        Text='<%# DisplayProductNameAndDiscontinuedStatus((string) Eval("ProductName"),
              (bool) Eval("Discontinued")) %>'>
    </asp:Label>
</h4>

為了顯示價格,我們可以直接將 UnitPriceLabel Label 的 Text 屬性設定為 方法所 DisplayPrice 傳回的值,就像我們在顯示產品名稱和 [DISCONTINUED] 文字時所做的一樣。 不過,我們改為傳入整個ProductsRow實例,而不是以純量輸入參數的形式傳入 UnitPrice

<asp:Label ID="UnitPriceLabel" runat="server"
    Text='<%# DisplayPrice((Northwind.ProductsRow)
          ((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>

有了對格式化函式的呼叫,請花點時間在瀏覽器中檢視我們的進度。 您的畫面看起來應該類似圖 5,其中包含文字 [DISCONTINUED] 的已停止產品,而那些產品的成本超過 $20.00,且其價格已取代為文字,請撥打價目。

此螢幕快照顯示 DataList 控件中所列的產品,其價格超過 $20.00 美元,並以文字取代 'Please call for a price quote',以及附加至已停止產品名稱的文字 '[DISCONTINUED]'。

圖 5:對於昂貴的產品,價格會以文字取代,請撥打價目表, (按兩下即可檢視完整大小的影像)

摘要

您可以使用兩種技術,根據數據格式化 DataList 或 Repeater 控件的內容。 第一個技巧是建立 事件的事件處理程式 ItemDataBound ,這會在數據源中的每個記錄系結至新的 DataListItemRepeaterItem時引發。 在 ItemDataBound 事件處理程式中,可以檢查目前的項目數據,然後將格式設定套用至範本的內容,或針對 DataListItem s 套用至整個專案本身。

或者,自定義格式可以透過格式化函式實現。 格式化函式是從 DataList 或 Repeater 範本叫用的方法,可傳回 HTML 以在其位置發出。 通常,格式化函式所傳回的 HTML 是由系結至目前專案的值所決定。 這些值可以傳遞至格式化函式,可以是純量值,或是傳入系結至專案 (的整個物件,例如 ProductsRow 實例) 。

快樂的程序設計!

關於作者

Scott Mitchell 是 1998 年以來,1998 年與 Microsoft Web 技術合作的 篇 ASP/ASP.NET 書籍和 4GuysFromRolla.com 作者。 Scott 是獨立的顧問、訓練者和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格連到,也可以透過其部落格來存取,網址為 http://ScottOnWriting.NET

特別感謝

本教學課程系列是由許多實用的檢閱者所檢閱。 本教學課程的首席檢閱者是 Yaakov Ellis、Randy Schmidt 和 Liz Shulok。 想要檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行放在 mitchell@4GuysFromRolla.com。