DataList と Repeater のカスタム ボタン (VB)
このチュートリアルでは、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 を参照)。
図 1: [Show Products] リンクをクリックすると、カテゴリの製品が箇条書きで表示されます (クリックするとフルサイズの画像が表示されます)。
手順 1: カスタム ボタン チュートリアル Web ページを追加する
カスタム ボタンを追加する方法を見る前に、まず、このチュートリアルに必要な ASP.NET ページを Web サイト プロジェクトに作成してみましょう。 まず、CustomButtonsDataListRepeater
という名前の新しいフォルダーを追加します。 次に、そのフォルダーに次の 2 つの ASP.NET ページを追加し、必ず各ページを Site.master
マスター ページに関連付けます:
Default.aspx
CustomButtons.aspx
図 2: カスタム ボタン関連のチュートリアルの ASP.NET ページを追加する
他のフォルダーと同様に、CustomButtonsDataListRepeater
フォルダーの Default.aspx
のセクションにチュートリアルが一覧表示されます。 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: カテゴリの一覧を追加する
このチュートリアルでは、すべてのカテゴリを一覧表示し、クリックすると関連するカテゴリの製品を箇条書きで表示する Show Products の LinkButton を備えた Repeater を作成する必要があります。 まず、システム内のカテゴリを一覧表示する単純な Repeater を作成します。 まず、CustomButtonsDataListRepeater
フォルダーの CustomButtons.aspx
ページを開きます。 ツールボックスからデザイナーに Repeater をドラッグし、その ID
プロパティを Categories
に設定します。 次に、Repeater のスマート タグから新しいデータ ソース コントロールを作成します。 具体的には、CategoriesDataSource
クラスの CategoriesBLL
メソッドからデータを選択する、GetCategories()
という名前の新しい ObjectDataSource コントロールを作成します。
図 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] ボタンをクリックすると、ポストバックが発生しますが、アクションはまだ実行されません。
図 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") %>'
を使用して現在のレコードの主キー値 CategoryID
を CommandArgument
プロパティにバインドします。 これら 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
クリックされたボタンのCommandArgument
プロパティの値CommandName
ボタンのCommandName
プロパティの値CommandSource
クリックされたボタン コントロールへの参照Item
クリックされたボタンを含むRepeaterItem
への参照で、Repeater にバインドされた各レコードはRepeaterItem
としてマニフェストされる
選択したカテゴリの CategoryID
は CommandArgument
プロパティを介して渡されるため、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 の 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
の値を使用して、実行するアクションを識別します。 ボタンは 1 つしかないので、ここで CommandName
を確認するのは議論の余地がありますが、習慣にするのは良いことです。 次に、選択したカテゴリのプロパティの CategoryID
が CommandArgument
プロパティから取得されます。 次に、テンプレートの 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
に設定します。
図 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行をドロップしてください。