このチュートリアルでは、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.aspxCustomButtons.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を使用して、現在のレコードの主キー値CommandArgumentCategoryArgument='<%# 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 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値を使用して、実行するアクションを識別します。 ここで 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にメッセージを送ってください。