データに基づいて DataList と Repeater を書式設定する (C#)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、テンプレート内の書式設定関数を使用するか、DataBound イベントを処理することによって、DataList コントロールと Repeater コントロールの外観を書式設定する方法の例について説明します。

はじめに

前のチュートリアルで説明したように、DataList には、その外観に影響を与えるスタイル関連のプロパティが多数用意されています。 特に、DataList の 、および SelectedItemStyle プロパティに既定の AlternatingItemStyleHeaderStyleItemStyleCSS クラスを割り当てる方法について説明しました。 これら 4 つのプロパティに加えて、DataList には、いくつかの名前を付けるために、他のスタイル関連のプロパティ (、 BorderWidthForeColorBackColorなどFont) が多数含まれています。 Repeater コントロールには、スタイル関連のプロパティは含まれません。 このようなスタイル設定は、Repeater のテンプレートのマークアップ内で直接行う必要があります。

ただし、多くの場合、データの書式設定方法はデータ自体によって異なります。 たとえば、製品を一覧表示するときに、製品情報が廃止された場合は薄い灰色のフォントの色で表示したい場合や、値が 0 の場合は強調表示 UnitsInStock する必要がある場合があります。 前のチュートリアルで説明したように、GridView、DetailsView、および FormView には、データに基づいて外観を書式設定する 2 つの異なる方法が用意されています。

  • イベントはDataBound、適切なDataBoundイベントのイベント ハンドラーを作成します。これは、データが各項目にバインドされた後に発生します (GridView の場合はイベントでしたRowDataBound。DataList と Repeater の場合はイベントですItemDataBound)。 そのイベント ハンドラーでは、バインドしたデータを調べて、決定を書式設定できます。 この手法は、「 データに基づくカスタム書式設定 」チュートリアルで確認しました。
  • DetailsView コントロールまたは GridView コントロールの TemplateFields、または FormView コントロールのテンプレートを使用する場合は、テンプレートの書式設定関数を、ASP.NET ページの分離コード クラス、ビジネス ロジック レイヤー、または Web アプリケーションからアクセスできるその他のクラス ライブラリに追加できます。 この書式設定関数は、任意の数の入力パラメーターを受け取ることができますが、テンプレートでレンダリングするには HTML を返す必要があります。 書式設定関数は、 GridView コントロールのチュートリアルの「TemplateFields の使用」で最初に 調べられました。

これらの書式設定手法はどちらも、DataList コントロールと Repeater コントロールで使用できます。 このチュートリアルでは、両方のコントロールに対して両方の手法を使用する例について説明します。

イベント ハンドラーのItemDataBound使用

データがデータ ソース コントロールから DataList にバインドされている場合、またはプログラムによってコントロールの DataSource プロパティにデータを割り当ててそのメソッドを DataBind() 呼び出すと、DataList イベント DataBinding が発生し、データ ソースが列挙され、各データ レコードが DataList にバインドされます。 DataList は、データ ソース内の各レコードに対して、現在のレコードにバインドされるオブジェクトを作成 DataListItem します。 このプロセス中、DataList は次の 2 つのイベントを発生させます。

  • ItemCreated が作成された後に DataListItem 発生する
  • ItemDataBound は、現在のレコードが にバインドされた後に発生します。 DataListItem

次の手順では、DataList コントロールのデータ バインディング プロセスについて説明します。

  1. DataList のイベントがDataBinding発生する

  2. データは DataList にバインドされます

    データ ソース内の各レコードについて

    1. オブジェクトを作成するDataListItem
    2. イベントを発生させますItemCreated
    3. レコードを にバインドする DataListItem
    4. イベントを発生させますItemDataBound
    5. コレクションに をDataListItem追加するItems

データを Repeater コントロールにバインドすると、まったく同じ一連の手順を進みます。 唯一の違いは、インスタンスが作成されるの DataListItem ではなく、Repeater が を使用 RepeaterItemすることです。

注意

DataList と Repeater がデータにバインドされている場合と GridView がデータにバインドされている場合にトランスパイルされる一連のステップの間にわずかな異常が発生している可能性があります。 データ バインディング プロセスの末尾で、GridView はイベントを DataBound 発生させますが、DataList コントロールも Repeater コントロールにもこのようなイベントはありません。 これは、DataList コントロールと Repeater コントロールが、前レベルと事後レベルのイベント ハンドラー パターンが一般的になる前に、ASP.NET 1.x の時間枠で作成されたためです。

GridView と同様に、データに基づいて書式設定するオプションの 1 つは、イベントのイベント ハンドラーを ItemDataBound 作成することです。 このイベント ハンドラーは、 または RepeaterItem にバインドされたデータをDataListItem検査し、必要に応じてコントロールの書式設定に影響します。

DataList コントロールの場合、項目全体の書式設定の変更は、標準Fontの 、ForeColorCssClassBackColor、 などのスタイル関連のプロパティを使用してDataListItem実装できます。 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.aspxFormatting.aspxレプリケートしたら、DataList の ID プロパティ DataList1 をよりわかりやすい ItemDataBoundFormattingExampleに変更します。 次に、ブラウザーで DataList を表示します。 図 1 に示すように、各製品の書式設定の違いは、背景色が交互に変化することです。

DataList コントロールに製品が一覧表示される

図 1: DataList コントロールに製品が一覧表示されている (フルサイズの画像を表示するをクリックします)

このチュートリアルでは、価格が $20.00 未満の製品の名前と単価の両方が黄色で強調表示されるように DataList を書式設定します。

手順 2: プログラムによって ItemDataBound イベント ハンドラー内のデータの値を決定する

価格が $20.00 以下の製品にのみカスタム書式が適用されるため、各製品の価格を決定できる必要があります。 DataList にデータをバインドする場合、DataList はデータ ソース内のレコードを列挙し、レコードごとに インスタンスを DataListItem 作成し、データ ソース レコードを に DataListItemバインドします。 特定のレコードのデータが現在 DataListItem のオブジェクトにバインドされると、DataList の ItemDataBound イベントが発生します。 このイベントのイベント ハンドラーを作成して、現在 DataListItem のデータ値を検査し、それらの値に基づいて、必要な書式設定の変更を行うことができます。

DataList の ItemDataBound イベントを作成し、次のコードを追加します。

protected void ItemDataBoundFormattingExample_ItemDataBound
    (object sender, DataListItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item ||
        e.Item.ItemType == ListItemType.AlternatingItem)
    {
        // Programmatically reference the ProductsRow instance bound
        // to this DataListItem
        Northwind.ProductsRow product =
            (Northwind.ProductsRow)((System.Data.DataRowView)e.Item.DataItem).Row;
        // See if the UnitPrice is not NULL and less than $20.00
        if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
        {
            // TODO: Highlight the product's name and price
        }
    }
}

DataList ItemDataBound のイベント ハンドラーの背後にある概念とセマンティクスは、Data に基づくカスタム書式設定チュートリアルの GridView のRowDataBoundイベント ハンドラーで使用されるものと同じですが、構文は若干異なります。 イベントがItemDataBound発生すると、DataListItemデータにバインドされた だけが(GridView のRowDataBoundイベント ハンドラーと同様に e.Rowではなく) を介してe.Item対応するイベント ハンドラーに渡されます。 DataList の ItemDataBound イベント ハンドラーは、ヘッダー行、フッター行、区切り行など、DataList に追加された 各行 に対して発生します。 ただし、製品情報はデータ行にのみバインドされます。 そのため、 イベントを ItemDataBound 使用して DataList にバインドされたデータを検査する場合は、まずデータ項目を使用していることを確認する必要があります。 これは、 プロパティをDataListItemItemTypeチェックすることで実現できます。このプロパティには、次の 8 つの値のいずれかを指定できます。

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

AlternatingItem``DataListItem の両方Itemで、DataList のデータ項目が構成されます。 または AlternatingItemItem使用していると仮定すると、現在DataListItemの にバインドされた実際ProductsRowのインスタンスにアクセスします。 s DataItem プロパティにはDataListItem、 オブジェクトへの参照がDataRowView含まれています。このRowプロパティは、実際ProductsRowのオブジェクトへの参照を提供します。

次に、インスタンスの UnitPrice プロパティをProductsRowチェックします。 Products テーブルの フィールドではUnitPrice値が許可NULLされるため、プロパティにアクセスUnitPriceする前に、最初に メソッドを使用してIsUnitPriceNull()値を持っているNULLかどうかを確認チェック必要があります。 値が UnitPrice でないNULL場合は、$20.00 未満かどうかを確認するチェック。 実際に $20.00 以下の場合は、カスタム書式を適用する必要があります。

手順 3: 製品名と価格を強調表示する

製品の価格が $20.00 未満であることがわかったら、残っているのは、その名前と価格を強調表示することです。 これを実現するには、まず、製品の名前と価格を表示する 内の Label コントロールをプログラムで ItemTemplate 参照する必要があります。 次に、黄色の背景を表示させる必要があります。 この書式設定情報は、Labels BackColor プロパティ (LabelID.BackColor = Color.Yellow) を直接変更することで適用できます。ただし、理想的には、すべての表示関連事項をカスケード スタイルシートで表現する必要があります。 実際には、データに基づくカスタム書式設定のチュートリアルで作成および説明した、 でStyles.css - AffordablePriceEmphasis定義された目的の書式設定を提供するスタイルシートが既に用意されています。

書式設定を適用するには、次のコードに示すように、単に 2 つの Label Web コントロール CssClass のプロパティを に AffordablePriceEmphasis設定します。

// Highlight the product name and unit price Labels
// First, get a reference to the two Label Web controls
Label ProductNameLabel = (Label)e.Item.FindControl("ProductNameLabel");
Label UnitPriceLabel = (Label)e.Item.FindControl("UnitPriceLabel");
// Next, set their CssClass properties
if (ProductNameLabel != null)
    ProductNameLabel.CssClass = "AffordablePriceEmphasis";
if (UnitPriceLabel != null)
    UnitPriceLabel.CssClass = "AffordablePriceEmphasis";

イベント ハンドラーが ItemDataBound 完了したら、ブラウザーでページを Formatting.aspx 見直します。 図 2 に示すように、価格が 20.00 ドル以下の製品の名前と価格の両方が強調表示されています。

20.00 ドル未満の製品が強調表示されている

図 2: $20.00 未満の製品が強調表示されています (フルサイズの画像を表示する場合はクリックします)

注意

DataList は HTML <table>としてレンダリングされるため、その DataListItem インスタンスにはスタイル関連のプロパティがあり、アイテム全体に特定のスタイルを適用するように設定できます。 たとえば、価格が $20.00 未満のときにアイテム 全体 を黄色で強調表示する場合は、Labels を参照するコードを置き換え、そのプロパティを CssClass 次のコード e.Item.CssClass = "AffordablePriceEmphasis" 行に設定できます (図 3 を参照)。

ただし、Repeater コントロールを構成する s では RepeaterItem 、このようなスタイル レベルのプロパティは提供されません。 そのため、Repeater にカスタム書式を適用するには、図 2 と同様に、Repeater のテンプレート内の Web コントロールにスタイル プロパティを適用する必要があります。

製品アイテム全体が 20.00 ドル以下の製品で強調表示されている

図 3: 製品アイテム全体が 20.00 ドル以下の製品で強調表示されている (フルサイズの画像を表示する をクリックします)

テンプレート内からの書式設定関数の使用

GridView コントロールのテンプレート フィールドの使用に関するチュートリアルでは、GridView TemplateField 内で書式設定関数を使用して、GridView の行にバインドされたデータに基づいてカスタム書式を適用する方法について説明しました。 書式設定関数は、テンプレートから呼び出し可能なメソッドであり、その代わりに出力される HTML を返します。 書式設定関数は、ASP.NET ページの分離コード クラスに配置することも、フォルダーまたは別のクラス ライブラリ プロジェクト内の App_Code クラス ファイルに一元化することもできます。 書式設定関数を ASP.NET ページの分離コード クラスから移動することは、複数の ASP.NET ページまたは他の ASP.NET Web アプリケーションで同じ書式設定関数を使用する場合に最適です。

書式設定関数を示すために、製品情報に、製品名の横にある [DISCONTINUED] というテキストが廃止された場合に含めます。 また、価格が $20.00 未満の場合は黄色で強調表示します (イベント ハンドラーの例で ItemDataBound 行ったように)。価格が $20.00 以上の場合は、実際の価格を表示するのではなく、代わりにテキストを表示します。価格見積もりを呼び出してください。 図 4 は、これらの書式設定ルールが適用された製品一覧のスクリーン ショットを示しています。

DataList コントロールにリストされている製品を示すスクリーンショット。製品の価格が $20.00 を超える場合は、

図 4: 高価な製品の場合、価格はテキストに置き換えられます。価格見積もりを呼び出してください (クリックするとフルサイズの画像が表示されます)

手順 1: 書式設定関数を作成する

この例では、必要に応じて製品名とテキスト [DISCONTINUED] を表示する 2 つの書式設定関数と、$20.00 未満の場合は強調表示された価格を表示する 1 つ、またはテキストを表示する 2 つの書式設定関数が必要です。それ以外の場合は価格見積もりを呼び出してください。 ASP.NET ページの分離コード クラスでこれらの関数を作成し、 と DisplayPriceという名前をDisplayProductNameAndDiscontinuedStatus付けます。 どちらのメソッドも HTML を返して文字列としてレンダリングする必要があり、ASP.NET ページの宣言構文部分から呼び出すには、両方とも マーク Protected (または Public) する必要があります。 これら 2 つのメソッドのコードは次のとおりです。

protected string DisplayProductNameAndDiscontinuedStatus
    (string productName, bool discontinued)
{
    // Return just the productName if discontinued is false
    if (!discontinued)
        return productName;
    else
        // otherwise, return the productName appended with the text "[DISCONTINUED]"
        return string.Concat(productName, " [DISCONTINUED]");
}
protected string DisplayPrice(Northwind.ProductsRow product)
{
    // If price is less than $20.00, return the price, highlighted
    if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
        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>";
}

メソッドはDisplayProductNameAndDiscontinuedStatus、 および discontinued データ フィールドの値をproductNameスカラー値として受け入れますがDisplayPrice、メソッドは (スカラー値ではなく) インスタンスを受け入れることProductsRowunitPrice注意してください。 どちらの方法でも機能します。ただし、書式設定関数がデータベースNULL値を含むことができるスカラー値 (; 値を許可NULLしないDiscontinued、 などUnitPrice) で動作している場合はProductName、これらのスカラー入力の処理に特別な注意を払う必要があります。

特に、入力パラメーターは型 Object である必要があります。これは、受信値が予期されるデータ型ではなくインスタンスである可能性 DBNull があるためです。 さらに、受信値がデータベースNULL値かどうかを判断するには、チェックを作成する必要があります。 つまり、 メソッドで価格を DisplayPrice スカラー値として受け入れる場合は、次のコードを使用する必要があります。

protected string DisplayPrice(object unitPrice)
{
    // If price is less than $20.00, return the price, highlighted
    if (!Convert.IsDBNull(unitPrice) && ((decimal) unitPrice) < 20)
        return string.Concat("<span class=\"AffordablePriceEmphasis\">",
                              ((decimal) unitPrice).ToString("C"), "</span>");
    else
        // Otherwise return the text, "Please call for a price quote"
        return "<span>Please call for a price quote</span>";
}

入力パラメーターは unitPriceObjectであり、条件ステートメントが が かどうかをunitPriceDBNull確認するように変更されていることに注意してください。 さらに、入力パラメーターは として渡されるため unitPriceObject10 進値にキャストする必要があります。

手順 2: DataList の ItemTemplate から書式設定関数を呼び出す

ASP.NET ページの分離コード クラスに書式設定関数が追加されたので、残っているのは、DataList から ItemTemplateこれらの書式設定関数を呼び出す方法です。 テンプレートから書式設定関数を呼び出すには、databinding 構文内に関数呼び出しを配置します。

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

DataList の ItemTemplateProductNameLabel Label Web コントロールでは、現在、そのプロパティに の結果を Text 割り当てることによって、製品の <%# Eval("ProductName") %>名前が表示されます。 名前とテキスト [DISCONTINUED] を表示するには、必要に応じて宣言構文を更新して、代わりに プロパティに メソッドの値をDisplayProductNameAndDiscontinuedStatus割り当てますText。 これを行う場合は、 構文を使用して製品の名前と廃止された値を Eval("columnName") 渡す必要があります。 Eval は 型 Objectの値を返しますが、 DisplayProductNameAndDiscontinuedStatus メソッドは 型 StringBooleanの入力パラメーターを受け取ります。したがって、メソッドによって Eval 返される値を、次のように、予期される入力パラメーター型にキャストする必要があります。

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

価格を表示するには、製品名と [DISCONTINUED] テキストを表示する場合と同じように、Label Text s プロパティを メソッドによってDisplayPrice返される値に設定UnitPriceLabelするだけです。 ただし、 をスカラー入力パラメーターとして渡す UnitPrice 代わりに、インスタンス全体 ProductsRow を渡します。

<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 ドルを超える製品の価格が、

図 5: 高価な製品の場合、価格はテキストに置き換えられます。価格見積もりを呼び出してください (クリックするとフルサイズの画像が表示されます)

まとめ

データに基づいて DataList コントロールまたは Repeater コントロールの内容を書式設定するには、2 つの手法を使用します。 最初の手法は、 イベントのイベント ハンドラーを ItemDataBound 作成することです。これは、データ ソース内の各レコードが新しい DataListItem または RepeaterItemにバインドされるときに発生します。 ItemDataBoundイベント ハンドラーでは、現在のアイテムのデータを調べてから、書式設定をテンプレートの内容に適用するか、または s の場合DataListItemはアイテム全体に適用できます。

または、書式設定関数を使用してカスタム書式設定を実現することもできます。 書式設定関数は、その代わりに出力する HTML を返す DataList または Repeater のテンプレートから呼び出すことができるメソッドです。 多くの場合、書式設定関数によって返される HTML は、現在のアイテムにバインドされている値によって決まります。 これらの値は、スカラー値として、または項目にバインドされているオブジェクト全体 (インスタンスなど) を渡すことによって、書式設定関数に ProductsRow 渡すことができます。

幸せなプログラミング!

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・自分自身 ASP.NET 24時間で2.0です。 にアクセスmitchell@4GuysFromRolla.comすることも、ブログを介して アクセスすることもできます。これは でhttp://ScottOnWriting.NET確認できます。

特別な感謝

このチュートリアル シリーズは、多くの役立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Yaakov Ellis、Randy Schmidt、Liz Shulok でした。 今後の MSDN 記事の確認に関心がありますか? その場合は、 に行mitchell@4GuysFromRolla.comをドロップしてください。