このチュートリアルでは、Repeater を使用してシステム内のカテゴリを一覧表示するインターフェイスを構築します。各カテゴリには、BulletedList コントロールを使用して関連する製品を表示するボタンが用意されています。
イントロダクション
過去 17 回の DataList と Repeater のチュートリアルでは、読み取り専用の例と、例の編集と削除の両方を作成しました。 DataList 内の機能の編集と削除を容易にするために、DataList ItemTemplate
にボタンを追加しました。このボタンをクリックするとポストバックが発生し、ボタンの CommandName
プロパティに対応する DataList イベントが発生しました。 たとえば、ItemTemplate
プロパティ値が Edit のCommandName
にボタンを追加すると、DataList のEditCommand
がポストバック時に起動し、CommandName
Delete を持つボタンはDeleteCommand
を発生させます。
[編集] ボタンと [削除] ボタンに加えて、DataList コントロールと Repeater コントロールには、ボタン、LinkButtons、ImageButtons を含めることもできます。ボタンをクリックすると、カスタム サーバー側ロジックを実行します。 このチュートリアルでは、Repeater を使用してシステム内のカテゴリを一覧表示するインターフェイスを構築します。 各カテゴリについて、Repeater には、BulletedList コントロールを使用してカテゴリに関連付けられている製品を表示するボタンが含まれます (図 1 を参照)。
図 1: [製品の表示] リンクをクリックすると、箇条書きのカテゴリの製品が表示されます (フルサイズの画像を表示する をクリックします)。
手順 1: カスタム ボタンチュートリアル Web ページの追加
カスタム ボタンを追加する方法を見る前に、まず、このチュートリアルに必要な ASP.NET ページを Web サイト プロジェクトに作成してみましょう。 まず、 CustomButtonsDataListRepeater
という名前の新しいフォルダーを追加します。 次に、次の 2 つの ASP.NET ページをそのフォルダーに追加し、各ページを Site.master
マスター ページに関連付けます。
Default.aspx
CustomButtons.aspx
図 2: カスタム Buttons-Related チュートリアルの ASP.NET ページを追加する
他のフォルダーと同様に、Default.aspx
フォルダーにCustomButtonsDataListRepeater
すると、そのセクションにチュートリアルが一覧表示されます。
SectionLevelTutorialListing.ascx
ユーザー コントロールがこの機能を提供していることを思い出してください。 ソリューション エクスプローラーからページのデザイン ビューにドラッグして、このユーザー コントロールを 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 サイトを表示します。 左側のメニューに、チュートリアルの編集、挿入、削除の項目が含まれるようになりました。
図 4: サイト マップにカスタム ボタン チュートリアルのエントリが含まれるようになりました
手順 2: カテゴリの一覧を追加する
このチュートリアルでは、すべてのカテゴリを一覧表示するRepeaterを作成し、その中に「製品を表示するリンク ボタン」を含める必要があります。このリンクボタンがクリックされると、関連するカテゴリの製品が箇条書きで表示されます。 まず、システム内のカテゴリを一覧表示する単純な Repeater を作成します。 まず、CustomButtons.aspx
フォルダーの CustomButtonsDataListRepeater
ページを開きます。 ツールボックスからデザイナーに Repeater をドラッグし、その ID
プロパティを Categories
に設定します。 次に、Repeater のスマート タグから新しいデータ ソース コントロールを作成します。 具体的には、CategoriesDataSource
クラスの CategoriesBLL
メソッドからデータを選択する、GetCategories()
という名前の新しい ObjectDataSource コントロールを作成します。
図 5: CategoriesBLL
クラスの GetCategories()
メソッドを使用するように ObjectDataSource を構成する (フルサイズの画像を表示する をクリックします)。
Visual Studio がデータ ソースに基づいて既定の ItemTemplate
を作成する DataList コントロールとは異なり、Repeater のテンプレートは手動で定義する必要があります。 さらに、Repeater のテンプレートは宣言によって作成および編集する必要があります (つまり、Repeater のスマート タグにはテンプレートの編集オプションはありません)。
左下隅にある [ソース] タブをクリックし、ItemTemplate
要素のカテゴリ名とその説明を段落タグに表示する<h3>
を追加します。各カテゴリ間の水平ルール (SeparatorTemplate
) を表示する<hr />
を含めます。 また、 Text
プロパティを [製品の表示] に設定して 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]\(製品の表示\) ボタンをクリックすると、ポストバックが発生しますが、アクションはまだ実行されません。
図 6: 各カテゴリの名前と説明が表示され、[製品の表示] リンク ボタンが表示されます (フルサイズの画像を表示する をクリックします)。
手順 3: [Show Products LinkButton]\(製品の表示\) リンク ボタンがクリックされたときに Server-Side ロジックを実行する
DataList または Repeater のテンプレート内の Button、LinkButton、または ImageButton がクリックされると、ポストバックが発生し、DataList または Repeater の ItemCommand
イベントが発生します。
ItemCommand
イベントに加えて、ボタンの CommandName
プロパティが予約文字列 (Delete、Edit、Cancel、Update、Select) のいずれかに設定されている場合、DataList コントロールは別のより具体的なイベントを発生させることもできますが、ItemCommand
イベントは常に発生します。
DataList または Repeater 内でボタンをクリックすると、多くの場合、クリックされたボタン ([編集] ボタンと [削除] ボタンの両方など、コントロール内に複数のボタンが存在する可能性がある場合) や、追加の情報 (ボタンがクリックされたアイテムの主キー値など) を渡す必要があります。 Button、LinkButton、および ImageButton には、 ItemCommand
イベント ハンドラーに値が渡される 2 つのプロパティが用意されています。
-
CommandName
テンプレート内の各ボタンを識別するために通常使用される文字列 -
CommandArgument
主キーの値など、一部のデータ フィールドの値を保持するために一般的に使用されます
この例では、LinkButton の CommandName
プロパティを ShowProducts に設定し、データ バインド構文CategoryID
を使用して、現在のレコードの主キー値CommandArgument
CategoryArgument='<%# Eval("CategoryID") %>'
プロパティにバインドします。 これら 2 つのプロパティを指定すると、LinkButton の宣言構文は次のようになります。
<asp:LinkButton runat="server" CommandName="ShowProducts"
CommandArgument='<%# Eval("CategoryID") %>' ID="ShowProducts">
Show Products</asp:LinkButton>
ボタンがクリックされると、ポストバックが発生し、DataList または Repeater の ItemCommand
イベントがトリガーされます。 イベント ハンドラーには、ボタンの CommandName
と CommandArgument
値が渡されます。
Repeater の ItemCommand
イベントのイベント ハンドラーを作成し、イベント ハンドラー ( e
という名前) に渡された 2 番目のパラメーターをメモします。 この 2 番目のパラメーターは RepeaterCommandEventArgs
型で、次の 4 つのプロパティがあります。
-
CommandArgument
クリックされたボタンの値 sCommandArgument
プロパティ -
CommandName
ボタン sCommandName
プロパティの値 -
CommandSource
クリックされたボタン コントロールへの参照 -
Item
クリックされたボタンを含むRepeaterItem
への参照です。Repeater にバインドされた各レコードはRepeaterItem
として表示されます。
選択したカテゴリの CategoryID
は CommandArgument
プロパティを介して渡されるため、 ItemCommand
イベント ハンドラーで選択したカテゴリに関連付けられている製品のセットを取得できます。 これらの製品は、まだ追加していないItemTemplate
のBulletedListコントロールにバインドすることができます。 残っているのは、BulletedList を追加し、それを ItemCommand
イベント ハンドラーで参照し、選択したカテゴリの製品セットにバインドすることです。これについては、手順 4 で説明します。
注
DataList の ItemCommand
イベント ハンドラーには、DataListCommandEventArgs
クラスと同じ 4 つのプロパティを提供するRepeaterCommandEventArgs
型のオブジェクトが渡されます。
手順 4: 箇条書きリストで選択したカテゴリの製品を表示する
選択したカテゴリの製品は、任意の数のコントロールを使用して、Repeater ItemTemplate
内に表示できます。 入れ子になった別の Repeater、DataList、DropDownList、GridView などを追加できます。 ただし、製品を箇条書きとして表示するため、BulletedList コントロールを使用します。
CustomButtons.aspx
ページの宣言型マークアップに戻り、製品の表示リンク ボタンの後のItemTemplate
に BulletedList コントロールを追加します。 BulletedLists の ID
を ProductsInCategory
に設定します。 BulletedList には、 DataTextField
プロパティで指定されたデータ フィールドの値が表示されます。このコントロールには製品情報がバインドされるため、 DataTextField
プロパティを ProductName
に設定します。
<asp:BulletedList ID="ProductsInCategory" DataTextField="ProductName"
runat="server"></asp:BulletedList>
ItemCommand
イベント ハンドラーで、e.Item.FindControl("ProductsInCategory")
を使用してこのコントロールを参照し、選択したカテゴリに関連付けられている製品のセットにバインドします。
Protected Sub Categories_ItemCommand _
(source As Object, e As RepeaterCommandEventArgs) _
Handles Categories.ItemCommand
If e.CommandName = "ShowProducts" Then
' Determine the CategoryID
Dim categoryID As Integer = Convert.ToInt32(e.CommandArgument)
' Get the associated products from the ProudctsBLL and
' bind them to the BulletedList
Dim products As BulletedList = _
CType(e.Item.FindControl("ProductsInCategory"), BulletedList)
Dim productsAPI As New ProductsBLL()
products.DataSource = productsAPI.GetProductsByCategoryID(categoryID)
products.DataBind()
End If
End Sub
ItemCommand
イベント ハンドラーでアクションを実行する前に、まず受信CommandName
の値を確認する必要があります。
ItemCommand
イベント ハンドラーはボタンがクリックされたときに発生するため、テンプレートに複数のボタンがある場合は、CommandName
値を使用して、実行するアクションを識別します。 ここで CommandName
を確認するのは無意味ですが、ボタンが1つしかないため、良い習慣を身につけることです。 次に、選択したカテゴリの CategoryID
が CommandArgument
プロパティから取得されます。 その後、テンプレート内の BulletedList コントロールが参照され、 ProductsBLL
クラスの GetProductsByCategoryID(categoryID)
メソッドの結果にバインドされます。
DataList のデータ の編集と削除の概要など、DataList 内のボタンを使用した前のチュートリアルでは、 DataKeys
コレクションを使用して特定の項目の主キー値を決定しました。 この方法は DataList で適切に機能しますが、Repeater には DataKeys
プロパティがありません。 代わりに、ボタンの CommandArgument
プロパティを使用して主キー値を指定したり、テンプレート内の非表示の Label Web コントロールに主キー値を割り当てたり、ItemCommand
を使用してe.Item.FindControl("LabelID")
イベント ハンドラーでその値を読み取ったりするなど、別の方法を使用する必要があります。
ItemCommand
イベント ハンドラーが完了したら、ブラウザーでこのページをテストします。 図 7 に示すように、[製品の表示] リンクをクリックするとポストバックが発生し、選択したカテゴリの製品が BulletedList に表示されます。 さらに、他のカテゴリの [製品の表示] リンクがクリックされた場合でも、この製品情報は残ります。
注
このレポートの動作を変更して、カテゴリの製品が一度に 1 つだけ一覧表示されるようにする場合は、BulletedList コントロールの EnableViewState
プロパティを False
に設定するだけです。
図 7: 選択したカテゴリの製品を表示するために BulletedList を使用します (フルサイズの画像を表示する をクリックします)。
概要
DataList コントロールと Repeater コントロールには、テンプレート内に任意の数のボタン、LinkButtons、または ImageButton を含めることができます。 このようなボタンをクリックすると、ポストバックが発生し、 ItemCommand
イベントが発生します。 カスタム サーバー側アクションをクリックするボタンに関連付けるには、 ItemCommand
イベントのイベント ハンドラーを作成します。 このイベント ハンドラーでは、最初に受信 CommandName
値を確認して、どのボタンがクリックされたかを確認します。 必要に応じて、ボタンの CommandArgument
プロパティを使用して追加情報を指定できます。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジを使用しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・セルフ ASP.NET 24時間で2.0です。 彼には mitchell@4GuysFromRolla.comで連絡できます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Dennis Patterson でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、mitchell@4GuysFromRolla.comにメッセージを送ってください。