マスター ページからコンテンツ ページと対話する (VB)

作成者: Scott Mitchell

マスター ページのコードからコンテンツ ページのメソッドの呼び出し、プロパティの設定などを行う方法について説明します。

はじめに

前のチュートリアルでは、コンテンツ ページをプログラムでマスター ページと対話させる方法について説明しました。 最後に追加された 5 つの製品を一覧表示する GridView コントロールを含むようにマスター ページを更新したことを思い出してください。 次に、ユーザーが新しい製品を追加できるコンテンツ ページを作成しました。 新しい製品を追加すると、コンテンツ ページは、追加した製品が含まれるように GridView を更新するようにマスター ページに指示する必要がありました。 この機能は、GridView にバインドされたデータを更新するパブリック メソッドをマスター ページに追加し、コンテンツ ページからそのメソッドを呼び出すことで実現されました。

コンテンツとマスター ページの相互作用の最も一般的な形式は、コンテンツ ページから発生します。 ただし、マスター ページで現在のコンテンツ ページを動作させる可能性があります。また、マスター ページにユーザーがコンテンツ ページにも表示されるデータを変更できるようにするユーザー インターフェイス要素が含まれている場合は、このような機能が必要になる場合があります。 GridView コントロールの製品情報を表示するコンテンツ ページと、ボタン コントロールを含むマスター ページについて考えてみます。ボタン コントロールをクリックすると、すべての製品の価格が 2 倍になります。 前のチュートリアルの例と同様に、新しい価格が表示されるように、二重価格ボタンをクリックした後に GridView を更新する必要がありますが、このシナリオでは、コンテンツ ページを動作させるために必要なマスター ページです。

このチュートリアルでは、マスター ページの呼び出し機能をコンテンツ ページで定義する方法について説明します。

イベント ハンドラーとイベント ハンドラーを使用したプログラムによる相互作用の作成

マスター ページからのコンテンツ ページ機能の呼び出しは、他の方法よりも困難です。 コンテンツ ページには 1 つのマスター ページがあるため、コンテンツ ページからプログラムによる操作を開始すると、どのようなパブリック メソッドとプロパティが自由に使用できるかがわかります。 ただし、マスター ページにはさまざまなコンテンツ ページがあり、それぞれに独自のプロパティとメソッドのセットがあります。 それでは、ランタイムまで呼び出されるコンテンツ ページがわからない場合に、そのコンテンツ ページで何らかのアクションを実行するコードをマスター ページに記述するにはどうすればよいですか?

ASP.NET Web コントロール (Button コントロールなど) について考えてみましょう。 ボタン コントロールは、任意の数の ASP.NET ページに表示でき、クリックされたことをページに通知するメカニズムが必要です。 これは 、イベントを使用して実現されます。 特に、Button コントロールは、クリックされるとイベントを Click 発生させます。Button を含む ASP.NET ページは、必要に応じて イベント ハンドラーを介してその通知に応答できます。

この同じパターンを使用して、マスター ページトリガー機能をコンテンツ ページに含めることができます。

  1. マスター ページにイベントを追加します。
  2. マスター ページがコンテンツ ページと通信する必要がある場合は常に、イベントを発生させます。 たとえば、マスター ページでユーザーが価格を 2 倍にしたことをコンテンツ ページに通知する必要がある場合、価格が 2 倍になった直後にイベントが発生します。
  3. 何らかのアクションを実行する必要があるイベント ハンドラーをコンテンツ ページに作成します。

このチュートリアルの残りの部分では、「概要」で説明されている例を実装します。つまり、データベース内の製品を一覧表示するコンテンツ ページと、価格を 2 倍にする Button コントロールを含むマスター ページです。

手順 1: コンテンツ ページに製品を表示する

最初のビジネスの順序は、Northwind データベースの製品を一覧表示するコンテンツ ページを作成することです。 (前のチュートリアル「コンテンツ ページからマスター ページを操作する」で、Northwind データベースをプロジェクトに追加しました。まず、 という名前Products.aspxのフォルダーに新しい ASP.NET ページを~/Admin追加し、マスター ページにSite.masterバインドします。 図 1 は、このページが Web サイトに追加された後のソリューション エクスプローラーを示しています。

管理 フォルダーに新しい ASP.NET ページを追加する

図 01: フォルダーに新しい ASP.NET ページを Admin 追加する (フルサイズの画像を表示する] をクリックします)

マスター ページのタイトル、メタ タグ、およびその他の HTML ヘッダーの指定に関するチュートリアルでは、ページのタイトルが明示的に設定されていない場合に生成する という名前BasePageのカスタム 基本ページ クラスを作成したことを思い出してください。 ページの Products.aspx 分離コード クラスに移動し、 から BasePage 派生させます ( System.Web.UI.Pageからではなく)。

最後に、このレッスンの Web.sitemap エントリを含むようにファイルを更新します。 [コンテンツ] の [マスター ページの相互作用] レッスンの下 <siteMapNode> に次のマークアップを追加します。

<siteMapNode url="~/Admin/Products.aspx" title="Master to Content Page Interaction" />

この <siteMapNode> 要素の追加は、レッスンの一覧に反映されます (図 5 を参照)。

Products.aspx戻ります。 のコンテンツ コントロール MainContentで、GridView コントロールを追加し、 という名前を付けます ProductsGrid。 GridView を という名前 ProductsDataSourceの新しい SqlDataSource コントロールにバインドします。

GridView を新しい SqlDataSource コントロールにバインドする

図 02: GridView を新しい SqlDataSource コントロールにバインドする (フルサイズの画像を表示する をクリックします)

Northwind データベースを使用するようにウィザードを構成します。 前のチュートリアルを実行した場合は、 に という名前NorthwindConnectionStringの接続文字列が既にWeb.config必要です。 図 3 に示すように、ドロップダウン リストからこの接続文字列を選択します。

Northwind データベースを使用するように SqlDataSource を構成する

図 03: Northwind データベースを使用するように SqlDataSource を構成する (フルサイズの画像を表示する をクリックします)

次に、ドロップダウン リストから Products テーブルを選択し、 列と UnitPrice 列を返して、データ ソース コントロールSELECTのステートメントをProductName指定します (図 4 を参照)。 [次へ] をクリックし、[完了] をクリックして、データ ソースの構成ウィザードを完了します。

Products テーブルから ProductName フィールドと UnitPrice フィールドを返します

図 04: テーブルから フィールドと UnitPrice フィールドをProducts返します ProductName (フルサイズの画像を表示する 場合は、ここをクリックします)

これですべて完了です。 ウィザードを完了すると、Visual Studio によって GridView に 2 つの BoundFields が追加され、SqlDataSource コントロールによって返される 2 つのフィールドがミラーされます。 GridView コントロールと SqlDataSource コントロールのマークアップは次のとおりです。 図 5 は、ブラウザーを使用して表示した場合の結果を示しています。

<asp:GridView ID="ProductsGrid" runat="server" AutoGenerateColumns="False" 
 DataSourceID="ProductsDataSource">
 <Columns>
 <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
 SortExpression="ProductName" />
 <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
 SortExpression="UnitPrice" />
 </Columns>
</asp:GridView>

<asp:SqlDataSource ID="ProductsDataSource" runat="server" 
 ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
 SelectCommand="SELECT [ProductName], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>

各製品とその価格は GridView に記載されています

図 05: 各製品とその価格が GridView に一覧表示されている (フルサイズの画像を表示する をクリックします)

注意

GridView の外観を自由にクリーンしてください。 表示される UnitPrice 値を通貨として書式設定したり、背景色やフォントを使用してグリッドの外観を改善したりすることが提案されています。 ASP.NET でのデータの表示と書式設定の詳細については、「データの 使用」チュートリアル シリーズを参照してください。

手順 2: マスター ページに二重価格ボタンを追加する

次のタスクは、ボタン Web コントロールをマスター ページに追加することです。このコントロールをクリックすると、データベース内のすべての製品の価格が 2 倍になります。 マスター ページをSite.master開き、[ツールボックス] から [ボタン] をDesignerにドラッグし、前のチュートリアルで追加した SqlDataSource コントロールの下RecentProductsDataSourceに配置します。 Button ID の プロパティを に DoublePrice 設定し、その Text プロパティを "Double Product Prices" に設定します。

次に、SqlDataSource コントロールをマスター ページに追加し、 という名前を付けます DoublePricesDataSource。 この SqlDataSource は、 ステートメントを UPDATE 実行してすべての価格を 2 倍にするために使用されます。 具体的には、その ConnectionString プロパティと UpdateCommand プロパティを適切な接続文字列と UPDATE ステートメントに設定する必要があります。 次に、Button がクリックされたときに、この SqlDataSource コントロールの Update メソッドを DoublePrice 呼び出す必要があります。 プロパティと UpdateCommand プロパティをConnectionString設定するには、SqlDataSource コントロールを選択し、プロパティ ウィンドウに移動します。 プロパティは ConnectionString 、ドロップダウン リストに既に Web.config 格納されている接続文字列を一覧表示します。図 6 に示すようにオプションを NorthwindConnectionString 選択します。

NorthwindConnectionString を使用するように SqlDataSource を構成する

図 06: を使用 NorthwindConnectionString するように SqlDataSource を構成する (クリックするとフルサイズの画像が表示されます)

プロパティをUpdateCommand設定するには、プロパティ ウィンドウで UpdateQuery オプションを見つけます。 このプロパティを選択すると、省略記号付きのボタンが表示されます。このボタンをクリックすると、図 7 に示す [コマンドとパラメーターのエディター] ダイアログ ボックスが表示されます。 ダイアログ ボックスのテキスト ボックスに次 UPDATE のステートメントを入力します。

UPDATE Products SET UnitPrice = UnitPrice * 2

このステートメントを実行すると、テーブル内Productsの各レコードのUnitPrice値が 2 倍になります。

SqlDataSource の UpdateCommand プロパティを設定する

図 07: SqlDataSource のプロパティを設定する (フルサイズのUpdateCommand画像を表示する場合はクリックします)

これらのプロパティを設定すると、Button コントロールと SqlDataSource コントロールの宣言型マークアップは次のようになります。

<asp:Button ID="DoublePrice" runat="server" 
 Text="Double Product Prices" />

<asp:SqlDataSource ID="DoublePricesDataSource" runat="server" 
 UpdateCommand="UPDATE Products SET UnitPrice = UnitPrice * 2" 
 ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
 ProviderName="<%$ ConnectionStrings:NorthwindConnectionString.ProviderName %>">
</asp:SqlDataSource>

残っているのは、Button がクリックされたときにメソッド UpdateDoublePrice 呼び出す方法です。 Button の Click イベント ハンドラーを DoublePrice 作成し、次のコードを追加します。

Protected Sub DoublePrice_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoublePrice.Click
 ' Double the prices
 DoublePricesDataSource.Update()
End Sub

この機能をテストするには、手順 1 で作成した ~/Admin/Products.aspx ページにアクセスし、[Double Product Price]\(二重製品価格\) ボタンをクリックします。 ボタンをクリックするとポストバックが発生し、Button のDoublePriceClickイベント ハンドラーが実行され、すべての製品の価格が 2 倍になります。 その後、ページが再レンダリングされ、マークアップが返され、ブラウザーに再表示されます。 ただし、コンテンツ ページの GridView には、[Double Product Price]\(二重製品価格\) ボタンがクリックされる前と同じ価格が表示されます。 これは、最初に GridView に読み込まれたデータの状態がビューステートに格納されているため、特に指示がない限りポストバックでは再読み込みされないためです。 別のページにアクセスしてページに ~/Admin/Products.aspx 戻ると、更新された価格が表示されます。

手順 3: 価格が 2 倍になったときにイベントを発生させる

ページ内 ~/Admin/Products.aspx の GridView は価格の倍額をすぐに反映しないため、ユーザーは、"Double Product Price" ボタンをクリックしなかったか、機能しなかったと考える場合があります。 彼らはもう少しボタンをクリックして、何度も何度も価格を2倍にしようとするかもしれません。 これを修正するには、コンテンツ ページのグリッドに、新しい価格が 2 倍にされた直後に表示されるようにする必要があります。

このチュートリアルで既に説明したように、ユーザーがボタンをクリックするたびに、マスター ページでイベントを DoublePrice 発生させる必要があります。 イベントは、1 つのクラス (イベントパブリッシャー) が他のクラス (イベント サブスクライバー) のセットに、興味深いことが発生したことを別のクラスに通知する方法です。 この例では、マスター ページはイベント発行元です。ボタンがクリックされたときに DoublePrice 気になるコンテンツ ページはサブスクライバーです。

クラスは、イベント ハンドラーを作成することによってイベントをサブスクライブ します。これは、発生しているイベントに応答して実行されるメソッドです。 パブリッシャーは、イベント デリゲートを定義することによって発生するイベントを定義 します。 イベント デリゲートは、イベント ハンドラーが受け入れる必要がある入力パラメーターを指定します。 .NET Frameworkでは、イベント デリゲートは値を返せず、2 つの入力パラメーターを受け入れます。

  • Objectイベント ソースを識別する 。
  • から派生したクラス System.EventArgs

イベント ハンドラーに渡される 2 番目のパラメーターには、イベントに関する追加情報を含めることができます。 基底EventArgsクラスは情報を渡しませんが、.NET Frameworkには、追加のプロパティを拡張EventArgsして含むクラスが多数含まれています。 たとえば、 CommandEventArgs インスタンスはイベントに応答するイベント ハンドラーに Command 渡され、2 つの情報プロパティ CommandArgumentCommandNameが含まれます。

注意

イベントの作成、発生、処理の詳細については、「単純な英語イベントとデリゲートとイベント デリゲート」を参照してください。

イベントを定義するには、次の構文を使用します。

Public Event eventName As eventDelegate

ユーザーがボタンをクリックした DoublePrice ときにのみコンテンツ ページに警告する必要があり、他の追加情報を渡す必要がないため、イベント デリゲート EventHandlerを使用できます。これは、2 番目のパラメーターとして 型の System.EventArgsオブジェクトを受け取るイベント ハンドラーを定義します。 マスター ページでイベントを作成するには、マスター ページの分離コード クラスに次のコード行を追加します。

Partial Class Site
 Inherits System.Web.UI.MasterPage

 Public Event PricesDoubled As EventHandler
 ...
End Class

上記のコードは、 という名前 PricesDoubledのマスター ページにパブリック イベントを追加します。 価格が2倍になった後、このイベントを発生させる必要があります。 イベントを発生させるためには、次の構文を使用します。

RaiseEvent eventName(sender, eventArgs)

sendereventArgs は、サブスクライバーのイベント ハンドラーに渡す値です。

イベント ハンドラーを次の DoublePriceClick コードで更新します。

Protected Sub DoublePrice_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoublePrice.Click
 ' Double the prices
 DoublePricesDataSource.Update()

 ' Refresh RecentProducts
 RecentProducts.DataBind()

 ' Raise the PricesDoubled event
 RaiseEvent PricesDoubled(Me, EventArgs.Empty)
End Sub

前と同様に、イベント ハンドラーはClick、SqlDataSource コントロールの Update メソッドをDoublePricesDataSource呼び出してすべての製品の価格を 2 倍にすることから始まります。 次に、イベント ハンドラーに 2 つの追加があります。 最初に RecentProducts 、GridView のデータが更新されます。 この GridView は、前のチュートリアルでマスター ページに追加され、最近追加された 5 つの製品を表示します。 この 5 つの製品の 2 倍の価格が表示されるように、このグリッドを更新する必要があります。 その後、イベントが発生します PricesDoubled 。 マスター ページ自体 (Me) への参照がイベント ソースとしてイベント ハンドラーに送信され、空 EventArgs のオブジェクトがイベント引数として送信されます。

手順 4: コンテンツ ページでのイベントの処理

この時点で、マスター ページは Button コントロールが PricesDoubled クリックされるたびにイベントを DoublePrice 発生させます。 ただし、これは戦いの半分にすぎません。サブスクライバーでイベントを処理する必要があります。 これには、イベント ハンドラーの作成とイベントの発生時にイベント ハンドラーが実行されるようにイベント配線コードを追加する 2 つの手順が含まれます。

まず、 という名前 Master_PricesDoubledのイベント ハンドラーを作成します。 マスター ページでイベントを定義した PricesDoubled 方法により、イベント ハンドラーの 2 つの入力パラメーターはそれぞれ 型 ObjectEventArgsである必要があります。 イベント ハンドラーで GridView の DataBind メソッドをProductsGrid呼び出して、グリッドにデータを再バインドします。

Private Sub Master_PricesDoubled(ByVal sender As Object, ByVal e As EventArgs)
 ' Rebind data to ProductsGrid
 ProductsGrid.DataBind()
End Sub

イベント ハンドラーのコードは完了しましたが、マスター ページの PricesDoubled イベントをこのイベント ハンドラーに結び付けられません。 サブスクライバーは、次の構文を使用してイベント ハンドラーにイベントを結び付けます。

AddHandler publisher.eventName, AddressOf methodName

publisher はイベント eventName を提供する オブジェクトへの参照であり、 methodName はサブスクライバーで定義されているイベント ハンドラーの名前です。

このイベント配線コードは、最初のページ訪問と後続のポストバックで実行する必要があり、イベントが発生する前のページ ライフサイクルの時点で発生する必要があります。 イベント配線コードを追加するのに適したタイミングは、ページ ライフサイクルの非常に早い段階で発生する PreInit ステージです。

イベント ハンドラーを開 ~/Admin/Products.aspx いて作成します Page_PreInit

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreInit
 ' TODO: Put event wiring logic here
End Sub

この配線コードを完了するには、コンテンツ ページからマスター ページへのプログラムによる参照が必要です。 前のチュートリアルで説明したように、これを行うには 2 つの方法があります。

  • 緩やかに型指定された Page.Master プロパティを適切なマスター ページの種類にキャストするか、
  • ページに ディレクティブを@MasterType.aspx追加し、厳密に型指定された Master プロパティを使用します。

後者のアプローチを使用しましょう。 ページの宣言型マークアップの上部に次 @MasterType のディレクティブを追加します。

<%@ MasterType VirtualPath="~/Site.master" %>

次に、イベント ハンドラーに次のイベント配線コードを Page_PreInit 追加します。

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreInit
 AddHandler Master.PricesDoubled, AddressOf Master_PricesDoubled
End Sub

このコードを配置すると、ボタンがクリックされるたびに、コンテンツ ページの DoublePrice GridView が更新されます。

図 8 と図 9 は、この動作を示しています。 図 8 は、最初にアクセスしたときのページを示しています。 GridView (マスター ページの左側の RecentProducts 列) と ProductsGrid GridView (コンテンツ ページ内) の両方の価格値に注意してください。 図 9 は、ボタンがクリックされた直後の同じ画面を DoublePrice 示しています。 ご覧のように、新しい価格は両方の GridView に瞬時に反映されます。

初期価格の値

図 08: 初期価格の値 (フルサイズの画像を表示する場合にクリックします)

Just-Doubled 価格は GridViews に表示されます

図 09: Just-Doubled 価格が GridViews に表示される (フルサイズの画像を表示する をクリックします)

まとめ

理想的には、マスター ページとそのコンテンツ ページは互いに完全に分離されており、対話のレベルは必要ありません。 ただし、マスター ページまたはコンテンツ ページから変更できるデータを表示するマスター ページまたはコンテンツ ページがある場合は、表示を更新できるように、データが変更されたときにマスター ページにコンテンツ ページ (またはその逆) を通知する必要がある場合があります。 前のチュートリアルでは、コンテンツ ページをプログラムでマスター ページと対話させる方法について説明しました。このチュートリアルでは、マスター ページで対話を開始する方法について説明しました。

コンテンツとマスター ページの間のプログラムによる操作は、コンテンツまたはマスター ページから開始できますが、使用される相互作用パターンは、配信元によって異なります。 違いは、コンテンツ ページには 1 つのマスター ページがありますが、マスター ページにはさまざまなコンテンツ ページが存在する可能性があるためです。 マスター ページをコンテンツ ページと直接やり取りするのではなく、マスター ページでイベントを発生させ、何らかのアクションが行われたことを通知することをお勧めします。 アクションを気にするコンテンツ ページでは、イベント ハンドラーを作成できます。

プログラミングに満足!

もっと読む

このチュートリアルで説明するトピックの詳細については、次のリソースを参照してください。

著者について

複数の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・自分自身 ASP.NET 24時間で3.5です。 Scott は、 または mitchell@4GuysFromRolla.com のブログから http://ScottOnWriting.NETアクセスできます。

特別な感謝

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