リピータ コントロールと DataList を使用した 2 つのページのマスター/詳細フィルター処理 (C#)
このチュートリアルでは、マスター/詳細レポートを 2 ページに分ける方法について説明します。 [マスター] ページでは、Repeater コントロールを使用してカテゴリの一覧をレンダリングします。このリストをクリックすると、ユーザーは 2 列の DataList で選択したカテゴリに属する製品が表示される [詳細] ページに移動します。
はじめに
前の チュートリアル では、DropDownLists を使用して "マスター" レコードを表示し、DataList を使用して "詳細" を表示するマスター/詳細レポートを 1 つの Web ページに表示する方法について説明しました。マスター/詳細レポートに使用されるもう 1 つの一般的なパターンは、1 つの Web ページにマスター レコードを、別のページに詳細を表示することです。 前の 2 ページにわたるマスター/詳細フィルターの チュートリアルでは、GridView を使用してこのパターンを調べ、システム内のすべてのサプライヤーを表示しました。 この GridView には HyperLinkField が含まれていました。これは 2 番目のページへのリンクとしてレンダリングされ、クエリ文字列内の を SupplierID
渡します。 2 番目のページでは、GridView を使用して、選択した仕入先から提供された製品を一覧表示しました。
このような 2 ページのマスター/詳細レポートは、DataList コントロールと Repeater コントロールを使用して実行することもできます。 唯一の違いは、DataList と Repeater のどちらも HyperLinkField コントロールのサポートを提供しない点です。 代わりに、HyperLink Web コントロールまたはアンカー HTML 要素 (<a>
) をコントロールの ItemTemplate
内に追加する必要があります。 HyperLink の NavigateUrl
プロパティまたはアンカーの属性は、宣言型またはプログラム型の href
アプローチを使用してカスタマイズできます。
このチュートリアルでは、Repeater コントロールを使用して、1 つのページの箇条書きのカテゴリを一覧表示する例について説明します。 各リスト アイテムには、カテゴリの名前と説明が含まれており、カテゴリ名は 2 番目のページへのリンクとして表示されます。 このリンクをクリックすると、ユーザーは 2 番目のページに移動し、選択したカテゴリに属する製品が DataList に表示されます。
手順 1: 箇条書きのカテゴリを表示する
マスター/詳細レポートを作成する最初の手順は、"マスター" レコードを表示することから始めます。 したがって、最初のタスクは、"マスター" ページにカテゴリを表示することです。 フォルダー内のページをCategoryListMaster.aspx
DataListRepeaterFiltering
開き、Repeater コントロールを追加し、スマート タグから新しい ObjectDataSource を追加することを選択します。 クラスGetCategories
の メソッドからCategoriesBLL
データにアクセスするように、新しい ObjectDataSource を構成します (図 1 を参照)。
図 1: クラスの メソッドを使用CategoriesBLL
するように ObjectDataSource を構成する (クリックするとフルサイズのGetCategories
画像が表示されます)
次に、各カテゴリ名と説明を箇条書きの項目として表示するように、Repeater のテンプレートを定義します。 詳細ページへの各カテゴリのリンクについて、まだ心配しないようにしましょう。 Repeater と ObjectDataSource の宣言型マークアップを次に示します。
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="ObjectDataSource1"
EnableViewState="False">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><%# Eval("CategoryName") %> - <%# Eval("Description") %></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
このマークアップが完了したら、ブラウザーを使用して進行状況を確認します。 図 2 に示すように、Repeater は、各カテゴリの名前と説明を示す箇条書きとしてレンダリングされます。
図 2: 各カテゴリは箇条書きアイテムとして表示されます (クリックするとフルサイズの画像が表示されます)
手順 2: カテゴリ名を [詳細] ページへのリンクに変換する
ユーザーが特定のカテゴリの "詳細" 情報を表示できるようにするには、各箇条書きアイテムへのリンクを追加する必要があります。このリンクをクリックすると、ユーザーは 2 番目のページ (ProductsForCategoryDetails.aspx
) に移動します。 この 2 番目のページでは、DataList を使用して、選択したカテゴリの製品が表示されます。 リンクがクリックされたカテゴリを特定するには、何らかのメカニズムを使用して、クリックされたカテゴリを 2 番目の CategoryID
ページに渡す必要があります。 1 つのページから別のページにスカラー データを転送する最も簡単で簡単な方法は、このチュートリアルで使用するオプションである querystring を使用することです。 特に、ページでは、 ProductsForCategoryDetails.aspx
選択した categoryID
値が という名前 CategoryID
のクエリ文字列フィールドを介して渡される必要があります。 たとえば、 が 1 の飲料カテゴリ CategoryID
の製品を表示するには、 にアクセス ProductsForCategoryDetails.aspx?CategoryID=1
します。
Repeater の箇条書き項目ごとにハイパーリンクを作成するには、HyperLink Web コントロールまたは HTML アンカー要素 (<a>
) を に追加する ItemTemplate
必要があります。 各行に同じハイパーリンクが表示されるシナリオでは、どちらの方法でも十分です。 リピーターの場合は、アンカー要素を使用することをお好みです。 アンカー要素を使用するには、Repeater の ItemTemplate を次のように更新します。
<li>
<a href='ProductsForCategoryDetails.aspx?CategoryID=<%# Eval("CategoryID") %>'>
<%# Eval("CategoryName") %>
</a> - <%# Eval("Description") %>
</li>
CategoryID
はアンカー要素のhref
属性内に直接挿入できることに注意してください。ただし、属性内href
の メソッドは文字列 ("CategoryID"
) を引用符で区切href
るのでEval
、属性の値をアポストロフィ (およびメモ引用符) で区切るようにしてください。 または、HyperLink Web コントロールを代わりに使用できます。
<li>
<asp:HyperLink runat="server" Text='<%# Eval("CategoryName") %>'
NavigateUrl='<%# "ProductsForCategoryDetails.aspx?CategoryID=" &
Eval("CategoryID") %>'>
</asp:HyperLink>
- <%# Eval("Description") %>
</li>
URL の静的部分 ( ) ProductsForCategoryDetails.aspx?CategoryID
が、文字列連結を使用して databinding 構文内のの結果 Eval("CategoryID")
にどのように追加されるかに注意してください。
HyperLink コントロールを使用する利点の 1 つは、必要に応じて、Repeater の ItemDataBound
イベント ハンドラーからプログラムでアクセスできることです。 たとえば、関連付けられた製品のないカテゴリのリンクとしてではなく、カテゴリ名をテキストとして表示できます。 このようなチェックは、イベント ハンドラーでプログラムによってItemDataBound
実行できます。関連付けられた製品のないカテゴリの場合、HyperLink の プロパティを空白のNavigateUrl
文字列に設定すると、その特定のカテゴリ名が (リンクとしてではなく) プレーン テキストとしてレンダリングされます。 イベント ハンドラーを使用したプログラム ロジックに 基づいて DataList と Repeater の内容を書式設定する方法の詳細については、DataList と Repeater のデータに基づく書式設定に関するチュートリアルを ItemDataBound
参照してください。
フォローしている場合は、ページでアンカー要素または HyperLink 制御アプローチを自由に使用できます。 この方法に関係なく、ブラウザーを介してページを表示する場合、各カテゴリ名は への ProductsForCategoryDetails.aspx
リンクとしてレンダリングされ、該当 CategoryID
する値を渡す必要があります (図 3 を参照)。
図 3: [カテゴリ名] リンク先 ProductsForCategoryDetails.aspx
(クリックするとフルサイズの画像が表示されます)
手順 3: 選択したカテゴリに属する製品を一覧表示する
ページが CategoryListMaster.aspx
完成したら、"詳細" ページ ProductsForCategoryDetails.aspx
の実装に注意を向ける準備ができました。 このページを開き、ツールボックスから Designer に DataList をドラッグし、そのプロパティを ID
にProductsInCategory
設定します。 次に、DataList のスマート タグから、新しい ObjectDataSource をページに追加し、 という名前を付けます ProductsInCategoryDataSource
。 クラスの GetProductsByCategoryID(categoryID)
メソッドをProductsBLL
呼び出すように構成します。INSERT タブ、UPDATE タブ、DELETE タブのドロップダウン リストを (None) に設定します。
図 4: クラスの メソッドを使用ProductsBLL
するように ObjectDataSource を構成する (クリックするとフルサイズのGetProductsByCategoryID(categoryID)
画像が表示されます)
メソッドは GetProductsByCategoryID(categoryID)
入力パラメーター (categoryID
) を受け取るので、データ ソースの選択ウィザードでは、パラメーターのソースを指定する機会が提供されます。 QueryStringField CategoryID
を使用して、パラメーター ソースを QueryString に設定します。
図 5: パラメーターのソースとして Querystring フィールド CategoryID
を使用する (フルサイズの画像を表示する をクリックします)
前のチュートリアルで説明したように、データ ソースの選択ウィザードを完了すると、Visual Studio によって DataList の が自動的に作成 ItemTemplate
され、各データ フィールドの名前と値が一覧表示されます。 このテンプレートは、製品の名前、サプライヤー、価格のみを一覧表示するテンプレートに置き換えます。 また、DataList の プロパティを RepeatColumns
2 に設定します。 これらの変更後、DataList と ObjectDataSource の宣言型マークアップは次のようになります。
<asp:DataList ID="ProductsInCategory" runat="server" DataKeyField="ProductID"
RepeatColumns="2" DataSourceID="ProductsInCategoryDataSource"
EnableViewState="False">
<ItemTemplate>
<h5><%# Eval("ProductName") %></h5>
<p>
Supplied by <%# Eval("SupplierName") %><br />
<%# Eval("UnitPrice", "{0:C}") %>
</p>
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ProductsInCategoryDataSource"
OldValuesParameterFormatString="original_{0}" runat="server"
SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
<SelectParameters>
<asp:QueryStringParameter Name="categoryID" QueryStringField="CategoryID"
Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
このページの動作を表示するには、ページから CategoryListMaster.aspx
開始します。次に、カテゴリの箇条書きのリンクをクリックします。 これを行うと、 に移動し ProductsForCategoryDetails.aspx
、 をクエリ文字列に沿って CategoryID
渡します。 その ProductsInCategoryDataSource
後、 の ProductsForCategoryDetails.aspx
ObjectDataSource は、指定されたカテゴリの製品のみを取得し、DataList に表示します。これにより、行ごとに 2 つの製品がレンダリングされます。 図 6 は、飲料を表示するときの の ProductsForCategoryDetails.aspx
スクリーンショットを示しています。
図 6: 行ごとに 2 つの飲料が表示されます (フルサイズの画像を表示するには、ここをクリックします)
手順 4: ProductsForCategoryDetails.aspxにカテゴリ情報を表示する
ユーザーが で CategoryListMaster.aspx
カテゴリをクリックすると、選択したカテゴリに ProductsForCategoryDetails.aspx
属する製品が表示されます。 ただし、 では ProductsForCategoryDetails.aspx
、選択されたカテゴリに関する視覚的な手掛かりはありません。 飲み物をクリックすることを意図したが、誤って Condiments をクリックしたユーザーは、 に到達 ProductsForCategoryDetails.aspx
した後に自分の間違いを認識する方法がありません。 この潜在的な問題を軽減するために、選択したカテゴリ (名前と説明) に関する情報をページの上部に ProductsForCategoryDetails.aspx
表示できます。
これを実現するには、 の Repeater コントロール ProductsForCategoryDetails.aspx
の上に FormView を追加します。 次に、FormView のスマート タグの という名前CategoryDataSource
の新しい ObjectDataSource をページに追加し、クラスの GetCategoryByCategoryID(categoryID)
メソッドをCategoriesBLL
使用するように構成します。
図 7: クラスの メソッドを使用してカテゴリにCategoriesBLL
関する情報にアクセスする (フルサイズのGetCategoryByCategoryID(categoryID)
画像を表示する をクリックします)
手順 3 で追加した ProductsInCategoryDataSource
ObjectDataSource と同様に、 CategoryDataSource
's データ ソースの構成ウィザードによって、メソッドの入力パラメーターのソースの入力が GetCategoryByCategoryID(categoryID)
求められます。 以前とまったく同じ設定を使用し、パラメーター ソースを QueryString に設定し、QueryStringField 値を に CategoryID
設定します (図 5 を参照)。
ウィザードが完了すると、Visual Studio によって FormView の 、EditItemTemplate
、および InsertItemTemplate
が自動的に作成ItemTemplate
されます。 読み取り専用インターフェイスを提供しているので、 と InsertItemTemplate
を自由に削除EditItemTemplate
できます。 また、FormView ItemTemplate
の を自由にカスタマイズできます。 余分なテンプレートを削除し、ItemTemplate をカスタマイズすると、FormView と ObjectDataSource の宣言型マークアップは次のようになります。
<asp:FormView ID="FormView1" runat="server" DataKeyNames="CategoryID"
DataSourceID="CategoryDataSource" EnableViewState="False" Width="100%">
<ItemTemplate>
<h3>
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Bind("CategoryName") %>' />
</h3>
<p>
<asp:Label ID="DescriptionLabel" runat="server"
Text='<%# Bind("Description") %>' />
</p>
</ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="CategoryDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategoryByCategoryID" TypeName="CategoriesBLL">
<SelectParameters>
<asp:QueryStringParameter Name="categoryID" Type="Int32"
QueryStringField="CategoryID" />
</SelectParameters>
</asp:ObjectDataSource>
図 8 は、ブラウザーを使用してこのページを表示するときのスクリーン ショットを示しています。
注意
FormView に加えて、ユーザーをカテゴリの一覧に戻す HyperLink コントロールを FormView の上に追加しました (CategoryListMaster.aspx
)。 このリンクを他の場所に配置するか、完全に省略してください。
図 8: ページの上部にカテゴリ情報が表示されるようになりました (クリックするとフルサイズの画像が表示されます)
手順 5: 選択したカテゴリに属する製品がない場合にメッセージを表示する
このページには CategoryListMaster.aspx
、関連する製品があるかどうかに関係なく、システム内のすべてのカテゴリが一覧表示されます。 ユーザーが関連付けられた製品のないカテゴリをクリックした場合、データ ソースには項目がないため、 の ProductsForCategoryDetails.aspx
DataList はレンダリングされません。 過去のチュートリアルで説明したように、GridView には、データ ソースにレコードがない場合に表示するテキスト メッセージを指定するために使用できるプロパティが用意 EmptyDataText
されています。 残念ながら、DataList も Repeater にもこのようなプロパティは含まれていません。
選択したカテゴリに一致する製品がないことをユーザーに通知するメッセージを表示するには、一致する製品がないことを示すメッセージを表示するプロパティが割り当てられているページ Text
に Label コントロールを追加する必要があります。 次に、DataList に項目が含まれているかどうかに基づいて、その Visible
プロパティをプログラムで設定する必要があります。
これを実現するには、まず DataList の下に Label を追加します。 その ID
プロパティを に NoProductsMessage
設定し、その Text
プロパティを "選択したカテゴリの製品はありません... " に設定します。次に、DataList にバインドされたデータの有無に基づいて、この Label Visible
のプロパティをプログラムで設定する ProductsInCategory
必要があります。 この割り当ては、データが DataList にバインドされた後に行う必要があります。 GridView、DetailsView、および FormView の場合、データバインドが完了した後に発生するコントロールのイベントの DataBound
イベント ハンドラーを作成できます。 ただし、DataList と Repeater のどちらもイベントを DataBound
使用できません。
この特定の例では、ページのイベントの Visible
前にデータが DataList に Page_Load
割り当てられるため、イベント ハンドラーで Label の Load
プロパティを割り当てることができます。 ただし、ObjectDataSource からのデータはページのライフサイクルの後半で DataList にバインドされる可能性があるため、この方法は一般的なケースでは機能しません。 たとえば、表示されるデータが別のコントロールの値に基づいている場合 (たとえば、DropDownList を使用して "マスター" レコードを保持するマスター/詳細レポートを表示する場合など)、ページのライフ サイクルのステージまで PreRender
データ Web コントロールにデータが再バインドされないことがあります。
すべてのケースで機能する 1 つの解決策は、 または AlternatingItem
の項目型Item
をFalse
バインドするときに、DataList ItemDataBound
の (または ItemCreated
) イベント ハンドラーで プロパティを に割り当てることVisible
です。 このような場合は、データ ソースに少なくとも 1 つのデータ項目があるため、Label を NoProductsMessage
非表示にすることができます。 このイベント ハンドラーに加えて、DataList DataBinding
のイベントのイベント ハンドラーも必要です。ここで、Label の Visible
プロパティを に初期化します True
。 イベントはイベントの DataBinding
前に ItemDataBound
発生するため、Label の Visible
プロパティは最初は に True
設定されます。ただし、データ項目がある場合は に False
設定されます。 次のコードは、このロジックを実装します。
protected void ProductsInCategory_DataBinding(object sender, EventArgs e)
{
// Show the Label
NoProductsMessage.Visible = true;
}
protected void ProductsInCategory_ItemDataBound(object sender, DataListItemEventArgs e)
{
// If we have a data item, hide the Label
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
NoProductsMessage.Visible = false;
}
Northwind データベース内のすべてのカテゴリは、1 つ以上の製品に関連付けられています。 この機能をテストするために、このチュートリアル用に Northwind データベースを手動で調整し、Produce カテゴリ (CategoryID
= 7) に関連付けられているすべての製品をシーフード カテゴリ (CategoryID
= 8) に再割り当てしました。 これは、新しいクエリを選択し、次UPDATE
のステートメントを使用して、サーバー エクスプローラーから実現できます。
UPDATE Products SET
CategoryID = 8
WHERE CategoryID = 7
それに応じてデータベースを更新した後、ページに CategoryListMaster.aspx
戻り、[生成] リンクをクリックします。 [生産] カテゴリに属する製品がなくなったため、"選択したカテゴリの製品はありません。" が表示されます。メッセージを表示します(図 9 を参照)。
図 9: 選択したカテゴリに属する製品がない場合は、メッセージが表示されます (フルサイズの画像を表示する をクリックします)。
まとめ
マスター/詳細レポートでは、マスター レコードと詳細レコードの両方を 1 つのページに表示できますが、多くの Web サイトでは 2 つの Web ページに分かれています。 このチュートリアルでは、"マスター" Web ページの Repeater と [詳細] ページに一覧表示されている関連製品を使用して、箇条書きリストにリストされているカテゴリを使用して、このようなマスター/詳細レポートを実装する方法について説明しました。 マスター Web ページの各リスト アイテムには、行 CategoryID
の値に沿って渡された詳細ページへのリンクが含まれていました。
指定したサプライヤーの製品を取得する詳細ページでは、 クラスの GetProductsByCategoryID(categoryID)
メソッドをProductsBLL
使用して行われました。 パラメーター値は categoryID
、パラメーター ソースとして querystring 値を CategoryID
使用して宣言によって指定されました。 また、FormView を使用して詳細ページにカテゴリの詳細を表示する方法と、選択したカテゴリに属する製品がない場合にメッセージを表示する方法についても説明しました。
幸せなプログラミング!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・自分自身 ASP.NET 24時間で2.0です。 にアクセスmitchell@4GuysFromRolla.comすることも、ブログを介して アクセスすることもできます。これは でhttp://ScottOnWriting.NET確認できます。
特別な感謝...
このチュートリアル シリーズは、多くの役立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Zack Jones と Liz Shulok でした。 今後の MSDN 記事の確認に関心がありますか? その場合は、 に行mitchell@4GuysFromRolla.comをドロップしてください。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示