DataList と Repeater のカスタム ボタン (C#)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、Repeater を使用してシステム内のカテゴリを一覧表示するインターフェイスを構築します。各カテゴリには、BulletedList コントロールを使用して関連する製品を表示するボタンが用意されています。

はじめに

過去 17 件の DataList と Repeater のチュートリアルでは、読み取り専用の例と、編集と削除の例を作成しました。 DataList 内の機能の編集と削除を容易にするために、DataList の ItemTemplate にボタンを追加しました。これをクリックするとポストバックが発生し、ボタンの CommandName プロパティに対応する DataList イベントが発生します。 たとえば、ItemTemplate プロパティ値が Edit のボタンを CommandName に追加すると、DataList の EditCommand がポストバック時に起動し、CommandName が Delete のものが DeleteCommand を発行します。

Edit ボタンと Delete ボタンに加えて、DataList と Repeater コントロールには、Button、LinkButton、ImageButton を含めることもできます。これらをクリックすると、カスタムのサーバー側ロジックが実行されます。 このチュートリアルでは、Repeater を使用してシステム内のカテゴリを一覧表示するインターフェイスを構築します。 各カテゴリについて、Repeater は、BulletedList コントロールを使用して、カテゴリに関連付けられている製品を表示するボタンを含めます (図 1 を参照)。

Clicking the Show Products Link Displays the Category s Products in a Bulleted List

図 1: [Show Products] リンクをクリックすると、カテゴリの製品が箇条書きで表示されます (クリックするとフルサイズの画像が表示されます)。

手順 1: カスタム ボタン チュートリアル Web ページを追加する

カスタム ボタンを追加する方法を見る前に、まず、このチュートリアルに必要な ASP.NET ページを Web サイト プロジェクトに作成してみましょう。 まず、CustomButtonsDataListRepeater という名前の新しいフォルダーを追加します。 次に、次の 2 つの ASP.NET ページをそのフォルダーに追加し、各ページを Site.master マスター ページに関連付けます。

  • Default.aspx
  • CustomButtons.aspx

Add the ASP.NET Pages for the Custom Buttons-Related Tutorials

図 2: カスタム ボタン関連のチュートリアルの ASP.NET ページを追加する

他のフォルダーと同様に、CustomButtonsDataListRepeater フォルダーの Default.aspx のセクションにチュートリアルが一覧表示されます。 SectionLevelTutorialListing.ascx ユーザー コントロールではこの機能が提供されていることを思い出してください。 このユーザー コントロールを Default.aspx に追加するには、ソリューション エクスプローラーからページのデザイン ビューにドラッグします。

Add the SectionLevelTutorialListing.ascx User Control to Default.aspx

図 3: SectionLevelTutorialListing.ascx ユーザー コントロールを Default.aspx に追加する (フルサイズの画像を表示する場合はこちらをクリック)

最後に、このページをエントリとして Web.sitemap ファイルに追加します。 具体的には、DataList と Repeater <siteMapNode> を使用したページングと並べ替えの後に、次のマークアップを追加します。

<siteMapNode
    url="~/CustomButtonsDataListRepeater/Default.aspx"
    title="Adding Custom Buttons to the DataList and Repeater"
    description="Samples of DataList and Repeater Reports that Include
                  Buttons for Performing Server-Side Actions">
    <siteMapNode
        url="~/CustomButtonsDataListRepeater/CustomButtons.aspx"
        title="Using Custom Buttons in the DataList and Repeater's Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons within templates." />
</siteMapNode>

Web.sitemap を更新した後、ブラウザーでチュートリアル Web サイトの表示を確認してみましょう。 左側のメニューに、チュートリアルの編集、挿入、削除の項目が含まれるようになりました。

The Site Map Now Includes the Entry for the Custom Buttons Tutorial

図 4: サイト マップにカスタム ボタン チュートリアルのエントリが含まれている

手順 2: カテゴリの一覧を追加する

このチュートリアルでは、すべてのカテゴリを一覧表示し、クリックすると関連するカテゴリの製品を箇条書きで表示する Show Products の LinkButton を備えた Repeater を作成する必要があります。 まず、システム内のカテゴリを一覧表示する単純な Repeater を作成します。 まず、CustomButtonsDataListRepeater フォルダーの CustomButtons.aspx ページを開きます。 ツールボックスからデザイナーに Repeater をドラッグし、その ID プロパティを Categories に設定します。 次に、Repeater のスマート タグから新しいデータ ソース コントロールを作成します。 具体的には、CategoriesDataSource クラスの CategoriesBLL メソッドからデータを選択する、GetCategories() という名前の新しい ObjectDataSource コントロールを作成します。

Configure the ObjectDataSource to Use the CategoriesBLL Class s GetCategories() Method

図 5: ObjectDataSource を CategoriesBLL クラスの GetCategories() メソッドを使用するように構成する (クリックするとフルサイズの画像が表示されます)

データ ソースに基づいて Visual Studio によって既定値 ItemTemplate が作成される DataList コントロールとは異なり、Repeater のテンプレートは手動で定義する必要があります。 さらに、Repeater のテンプレートは宣言によって作成および編集する必要があります (つまり、Repeater のスマート タグに [テンプレートの編集] オプションはありません)。

左下隅にある [ソース] タブをクリックし、ItemTemplate (<h3> 要素にカテゴリ名を表示し、その説明を段落タグに表示) を追加します。各カテゴリ間に、水平線 (<hr />) を表示する SeparatorTemplate を含めます。 また、Text プロパティを Show Products に設定した LinkButton も追加します。 これらの手順を完了すると、ページの宣言型マークアップは次のようになります。

<asp:Repeater ID="Categories" DataSourceID="CategoriesDataSource"
    runat="server">
    <ItemTemplate>
        <h3><%# Eval("CategoryName") %></h3>
        <p>
            <%# Eval("Description") %>
            [<asp:LinkButton runat="server" ID="ShowProducts">
                Show Products</asp:LinkButton>]
        </p>
    </ItemTemplate>
    <SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

図 6 は、ブラウザーで表示した場合のページを示しています。 各カテゴリ名と説明が一覧表示されます。 [Show Products] ボタンをクリックすると、ポストバックが発生しますが、アクションはまだ実行されません。

Each Category s Name and Description is Displayed, Along with a Show Products LinkButton

図 6: 各カテゴリの名前と説明が、Show Products の LinkButton とともに表示される (クリックするとフルサイズの画像が表示されます)

手順 3: Show Products の LinkButton がクリックされたときにサーバー側ロジックを実行する

DataList または Repeater のテンプレート内の Button、LinkButton、または ImageButton がクリックされると、ポストバックが発生し、DataList または Repeater の ItemCommand イベントが発生します。 ItemCommand イベントに加え、ボタンの CommandName プロパティが予約文字列 (Delete、Edit、Cancel、Update、または Select) のいずれかに設定されていると、DataList コントロールが別のより具体的なイベントを発生させることがありますが、ItemCommand イベントは常に発生します。

DataList または Repeater 内でボタンがクリックされると、多くの場合、クリックされたボタン ([Edit] と [Delete] ボタンなど、コントロール内に複数のボタンがある場合) や、追加の情報 (ボタンがクリックされたアイテムの主キー値など) を渡す必要があります。 Button、LinkButton、ImageButton には 2 つのプロパティがあり、その値は ItemCommand イベント ハンドラーに渡されます。

  • CommandName テンプレート内の各ボタンを識別するために通常使用される文字列
  • CommandArgument 主キーの値など、一部のデータ フィールドの値を保持するために一般的に使用される

この例では、LinkButton の CommandName プロパティを ShowProducts に設定し、データ バインド構文 CategoryArgument='<%# Eval("CategoryID") %>' を使用して現在のレコードの主キー値 CategoryIDCommandArgument プロパティにバインドします。 これら 2 つのプロパティを指定すると、LinkButton の宣言構文は次のようになります。

<asp:LinkButton runat="server" CommandName="ShowProducts"
    CommandArgument='<%# Eval("CategoryID") %>' ID="ShowProducts">
    Show Products</asp:LinkButton>

ボタンがクリックされるとポストバックが発生し、DataList または Repeater の ItemCommand イベントが発生します。 イベント ハンドラーには、ボタンの CommandNameCommandArgument 値が渡されます。

Repeater の ItemCommand イベントのイベント ハンドラーを作成し、イベント ハンドラー (e という名前) に渡された 2 番目のパラメーターを書き留めます。 この 2 番目のパラメーターの型は RepeaterCommandEventArgs で、次の 4 つのプロパティがあります。

  • CommandArgument クリックされたボタンの CommandArgument プロパティの値
  • CommandName ボタンの CommandName プロパティの値
  • CommandSource クリックされたボタン コントロールへの参照
  • Item クリックされたボタンを含む RepeaterItem への参照で、Repeater にバインドされた各レコードは RepeaterItem としてマニフェストされる

選択したカテゴリの CategoryIDCommandArgument プロパティを介して渡されるため、ItemCommand イベント ハンドラーで選択したカテゴリに関連付けられている製品のセットを取得できます。 これらの製品は、(まだ追加していない) ItemTemplate の BulletedList コントロールにバインドできます。 後は、BulletedList を追加し、それを ItemCommand イベント ハンドラーで参照し、選択したカテゴリについて製品セットにバインドします。これについては、手順 4 で説明します。

Note

DataList の ItemCommand イベント ハンドラーには、型 DataListCommandEventArgs のオブジェクトが渡されます。これは、RepeaterCommandEventArgs クラスと同様に 4 つのプロパティを提供します。

手順 4: 選択したカテゴリの製品を箇条書きで表示する

選択したカテゴリの製品は、任意の数のコントロールを使用して Repeater の ItemTemplate 内に表示できます。 入れ子になった別の Repeater、DataList、DropDownList、GridView などを追加することもできます。 ただし、製品は箇条書きで表示したいため、ここでは BulletedList コントロールを使用します。 CustomButtons.aspx ページの宣言型マークアップに戻り、BulletedList コントロールを ItemTemplate の "Show Products" LinkButton の後に追加します。 BulletedList の IDProductsInCategory に設定します。 BulletedList は、DataTextField プロパティを使用して指定されたデータ フィールドの値を表示します。このコントロールには製品情報がバインドされるため、DataTextField プロパティを ProductName に設定します。

<asp:BulletedList ID="ProductsInCategory" DataTextField="ProductName"
    runat="server"></asp:BulletedList>

ItemCommand イベント ハンドラーで、e.Item.FindControl("ProductsInCategory") を使用してこのコントロールを参照し、選択したカテゴリに関連付けられている製品のセットにバインドします。

protected void Categories_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    if (e.CommandName == "ShowProducts")
    {
        // Determine the CategoryID
        int categoryID = Convert.ToInt32(e.CommandArgument);
        // Get the associated products from the ProudctsBLL and bind
        // them to the BulletedList
        BulletedList products =
            (BulletedList)e.Item.FindControl("ProductsInCategory");
        ProductsBLL productsAPI = new ProductsBLL();
        products.DataSource =
            productsAPI.GetProductsByCategoryID(categoryID);
        products.DataBind());
    }
}

ItemCommand イベント ハンドラーでアクションを実行する前に、まず受信した CommandName の値を確認することが賢明です。 ItemCommand イベント ハンドラーは、いずれかのボタンがクリックされたときに発生するため、テンプレートに複数のボタンがある場合は、CommandName の値を使用して、実行するアクションを識別します。 ボタンは 1 つしかないので、ここで CommandName を確認するのは議論の余地がありますが、習慣にするのは良いことです。 次に、選択したカテゴリのプロパティの CategoryIDCommandArgument プロパティから取得されます。 次に、テンプレートの BulletedList コントロールが参照され、ProductsBLL クラスの GetProductsByCategoryID(categoryID) メソッドの結果にバインドされます。

DataList 内のボタンを使用した以前のチュートリアル (「DataList のデータの編集と削除の概要」など) では、DataKeys コレクションを使用して、特定の項目の主キー値を決定していました。 この方法は DataList では適切に機能しますが、Repeater には DataKeys プロパティがありません。 代わりに、主キーの値を指定する別の方法を使用する必要があります。たとえば、ボタンの CommandArgument プロパティを使用したり、テンプレート内の非表示の Label Web コントロールに主キー値を割り当てて、e.Item.FindControl("LabelID") を使用して ItemCommand イベント ハンドラーでその値を読み取ったりするなどです。

ItemCommand イベント ハンドラーが完了したら、少し時間を取って、ブラウザーでこのページをテストします。 図 7 に示すように、[Show Products] リンクをクリックするとポストバックが発生し、選択したカテゴリの製品が BulletedList に表示されます。 さらに、他のカテゴリの [Show Products] リンクがクリックされた場合も、この製品情報は残ることに注意してください。

Note

このレポートの動作を変更して、一度に 1 つのカテゴリの製品のみが一覧表示されるようにするには、BulletedList コントロールの EnableViewState プロパティを False に設定します。

A BulletedList is used to Display the Products of the Selected Category

図 7: BulletedList を使用して、選択したカテゴリの製品を表示する (クリックするとフルサイズの画像が表示されます)

まとめ

DataList コントロールと Repeater コントロールでは、テンプレート内に任意の数の Button、LinkButton、または ImageButton を含めることができます。 このようなボタンをクリックすると、ポストバックが発生し、ItemCommand イベントが発生します。 カスタム サーバー側のアクションをクリックされるボタンに関連付けるには、ItemCommand イベントのイベント ハンドラーを作成します。 このイベント ハンドラーは最初に、受信する CommandName 値をチェックして、どのボタンがクリックされたかを判断します。 必要に応じて、ボタンの CommandArgument プロパティを使用して追加情報を指定できます。

プログラミングに満足!

著者について

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

特別な感謝

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