次の方法で共有


プログラムでマスター ページを指定する (VB)

作成者: Scott Mitchell

PreInit イベント ハンドラーを使用して、コンテンツ ページのマスター ページをプログラムで設定します。

はじめに

マスター ページを使用した Site-Wide レイアウトの作成」の第 1 例以降、すべてのコンテンツ ページは ディレクティブの @Page 属性をMasterPageFile使用してマスター ページを宣言的に参照しています。 たとえば、次 @Page のディレクティブは、コンテンツ ページをマスター ページ Site.masterにリンクします。

<%@ Page Language="C#" MasterPageFile="~/Site.master"... %>

Page名前空間の System.Web.UI クラスには、コンテンツ ページのマスター ページへのパスを返す プロパティが含まれていますMasterPageFile。これは、 ディレクティブによって@Page設定されるこのプロパティです。 このプロパティを使用して、コンテンツ ページのマスター ページをプログラムで指定することもできます。 この方法は、ユーザーがページにアクセスするなど、外部要因に基づいてマスター ページを動的に割り当てる場合に便利です。

このチュートリアルでは、Web サイトに 2 つ目のマスター ページを追加し、実行時に使用するマスター ページを動的に決定します。

手順 1: ページのライフサイクルを見る

コンテンツ ページである ASP.NET ページの Web サーバーに要求が到着するたびに、ASP.NET エンジンはページの Content コントロールをマスター ページの対応する ContentPlaceHolder コントロールに融合する必要があります。 この融合により、1 つのコントロール階層が作成され、一般的なページ ライフサイクルを進めることができます。

図 1 は、この融合を示しています。 図 1 の手順 1 は、初期コンテンツとマスター ページ コントロール階層を示しています。 PreInit ステージの末尾に、ページ内のコンテンツ コントロールがマスター ページの対応する ContentPlaceHolders に追加されます (手順 2)。 この融合後、マスター ページは融合されたコントロール階層のルートとして機能します。 その後、この融合されたコントロール階層がページに追加され、最終的なコントロール階層が生成されます (手順 3)。 結果として、ページのコントロール階層に融合されたコントロール階層が含まれます。

PreInit ステージ中にマスター ページとコンテンツ ページのコントロール階層が結合される

図 01: PreInit ステージ中にマスター ページとコンテンツ ページのコントロール階層が結合されている (フルサイズの画像を表示する をクリックします)

手順 2: コードからプロパティを設定するMasterPageFile

この融合のマスター ページ の部分は、オブジェクトMasterPageFileの プロパティのPage値によって異なります。 ディレクティブで 属性をMasterPageFile@Page設定すると、ページのライフサイクルの最初のMasterPageFileステージである初期化ステージの間に の プロパティを割り当てるPageという正味の効果があります。 または、プログラムでこのプロパティを設定することもできます。 ただし、図 1 の融合が行われる前に、このプロパティを設定することが不可欠です。

PreInit ステージの開始時に、オブジェクトはイベントをPage発生させ、そのPreInitメソッドをOnPreInit呼び出します。 マスター ページをプログラムで設定するには、イベントの PreInit イベント ハンドラーを作成するか、 メソッドを OnPreInit オーバーライドします。 両方のアプローチを見てみましょう。

まず、サイトのホームページの分離コード クラス ファイルを開 Default.aspx.vbきます。 次のコードを入力して、ページのイベントの PreInit イベント ハンドラーを追加します。

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit 
End Sub

ここから プロパティを MasterPageFile 設定できます。 値 "~/Site.master" を プロパティに割り当てるようにコードを MasterPageFile 更新します。

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit 
 Me.MasterPageFile = "~/Site.master"
End Sub

ブレークポイントを設定してデバッグを開始すると、ページにアクセスしたときDefault.aspxや、このページへのポストバックが発生するたびに、イベント ハンドラーが実行されMasterPageFilePage_PreInitプロパティが "~/Site.master" に割り当てられることがわかります。

または、クラスの OnPreInit メソッドをPageオーバーライドし、そこで プロパティをMasterPageFile設定することもできます。 この例では、特定のページでマスター ページを設定するのではなく、 から BasePage設定してみましょう。 マスター ページのタイトル、メタ タグ、およびその他の HTML ヘッダーの指定に関するチュートリアルで、カスタム 基本ページ クラス (BasePage) を作成したことを思い出してください。 現在BasePage、クラスの OnLoadComplete メソッドをPageオーバーライドします。ここで、サイト マップ データに基づいてページのTitleプロパティを設定します。 を に更新 BasePage し、 メソッドを OnPreInit オーバーライドしてプログラムでマスター ページを指定してみましょう。

Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
 Me.MasterPageFile = "~/Site.master" 
 MyBase.OnPreInit(e)
End Sub

すべてのコンテンツ ページは から BasePage派生しているため、すべてのコンテンツ ページにプログラムによってマスター ページが割り当てられます。 この時点で、 のPreInitDefault.aspx.vbイベント ハンドラーは余分です。自由に削除できます。

ディレクティブについて@Page

少し混乱を招く可能性があるのは、コンテンツ ページのMasterPageFileプロパティが、クラスのメソッドでBasePageプログラムによって、および各コンテンツ ページ@Pageの ディレクティブの OnPreInit 属性を使用してMasterPageFile、2 つの場所で指定されているということです。

ページ ライフサイクルの最初のステージは、初期化ステージです。 この段階では、Pageオブジェクトの MasterPageFile プロパティに ディレクティブ内@Pageの 属性のMasterPageFile値が割り当てられます (指定されている場合)。 PreInit ステージは初期化ステージに従います。ここでは、プログラムによってオブジェクトの MasterPageFile プロパティをPage設定し、ディレクティブから割り当てられた値を@Page上書きします。 オブジェクトの プロパティをPageプログラムで設定しているため、エンド ユーザーのMasterPageFileエクスペリエンスに影響を与えることなく、 ディレクティブから @Page 属性を削除MasterPageFileできます。 これを理解するには、 内の ディレクティブDefault.aspxから 属性をMasterPageFile@Page削除し、ブラウザーからページにアクセスします。 予想どおり、出力は 属性が削除される前と同じです。

プロパティが ディレクティブを MasterPageFile 使用して @Page 設定されているか、プログラムによって設定されるかは、エンド ユーザーのエクスペリエンスに関係しません。 ただし、 ディレクティブの MasterPageFile@Page 属性は、デザイン時に Visual Studio によって使用され、Designerで WYSIWYG ビューが生成されます。 Visual Studio で にDefault.aspx戻り、Designerに移動すると、"マスター ページ エラー: ページにはマスター ページ参照を必要とするコントロールがありますが、何も指定されていません" というメッセージが表示されます (図 2 を参照)。

つまり、Visual Studio で豊富なデザイン時エクスペリエンスを@Page実現するには、 ディレクティブに 属性を残すMasterPageFile必要があります。

Visual Studio では、<span クラス=@Page ディレクティブの MasterPageFile 属性を使用してデザイン ビューをレンダリングします" />

図 02: Visual Studio はディレクティブのMasterPageFile属性を@Page使用してデザイン ビューをレンダリングします (フルサイズの画像を表示する 場合はクリックします)

手順 3: 代替マスター ページの作成

コンテンツ ページのマスター ページは実行時にプログラムで設定できるため、外部条件に基づいて特定のマスター ページを動的に読み込むことができます。 この機能は、サイトのレイアウトがユーザーによって異なる必要がある場合に役立ちます。 たとえば、ブログ エンジン Web アプリケーションでは、各レイアウトが異なるマスター ページに関連付けられているブログのレイアウトをユーザーが選択できる場合があります。 実行時に、訪問者がユーザーのブログを表示している場合、Web アプリケーションはブログのレイアウトを決定し、対応するマスター ページをコンテンツ ページに動的に関連付ける必要があります。

いくつかの外部条件に基づいて、実行時にマスター ページを動的に読み込む方法を見てみましょう。 現在、この Web サイトにはマスター ページSite.master () が 1 つだけ含まれています。 実行時にマスター ページを選択する方法を示すために、別のマスター ページが必要です。 この手順では、新しいマスター ページの作成と構成に焦点を当てます。 手順 4 では、実行時に使用するマスター ページを決定します。

という名前 Alternate.masterのルート フォルダーに新しいマスター ページを作成します。 また、 という名前 AlternateStyles.cssの Web サイトに新しいスタイル シートを追加します。

別のマスター ページと CSS ファイルを Web サイトに追加する

図 03: 別のマスター ページと CSS ファイルを Web サイトに追加する (クリックするとフルサイズの画像が表示されます)

マスター ページは Alternate.master 、ページの上部にタイトルが中央に表示され、ネイビーの背景に表示されるように設計しました。 左側の列を指定し、そのコンテンツを ContentPlaceHolder コントロールの下 MainContent に移動しました。これは、ページの幅全体にまたがっています。 さらに、順序付けられていないレッスンリストを作成し、上 MainContentの水平リストに置き換えました。 また、マスター ページで使用されるフォントと色も更新しました (また、拡張機能では、そのコンテンツ ページ)。 図 4 は、マスター ページを使用する場合をAlternate.master示していますDefault.aspx

注意

ASP.NET には、 テーマを定義する機能が含まれています。 Theme は、実行時にページに適用できる画像、CSS ファイル、およびスタイル関連の Web コントロール プロパティ設定のコレクションです。 テーマは、サイトのレイアウトが表示される画像と CSS ルールによってのみ異なる場合に行く方法です。 異なる Web コントロールの使用や、レイアウトが大幅に異なるなど、レイアウトが大幅に異なる場合は、個別のマスター ページを使用する必要があります。 テーマの詳細については、このチュートリアルの最後にある「その他の読み取り」セクションを参照してください。

コンテンツ ページで新しい外観を使用できるようになりました

図 04: コンテンツ ページで新しい外観を使用できるようになりました (クリックするとフルサイズの画像が表示されます)

マスター ページとコンテンツ ページのマークアップが融合されると、 MasterPage クラスは、コンテンツ ページ内のすべての Content コントロールがマスター ページの ContentPlaceHolder を参照していることを確認します。 存在しない ContentPlaceHolder を参照する Content コントロールが見つかった場合、例外がスローされます。 つまり、コンテンツ ページに割り当てられているマスター ページには、コンテンツ ページ内のコンテンツ コントロールごとに ContentPlaceHolder が必要です。

Site.masterマスター ページには、次の 4 つの ContentPlaceHolder コントロールが含まれています。

  • head
  • MainContent
  • QuickLoginUI
  • LeftColumnContent

当社のウェブサイトのコンテンツページの一部には、1つまたは2つのコンテンツコントロールが含まれています。その他には、使用可能な ContentPlaceHolders ごとに Content コントロールが含まれます。 すべての ContentPlaceHolders Site.master の Content コントロールを持つコンテンツ ページに新しいマスター ページ (Alternate.master) を割り当てることができる場合は、 と同じ ContentPlaceHolder コントロールSite.masterも含める必要Alternate.masterがあります。

マスター ページを Alternate.master 私のページと似た外観にするには (図 4 を参照)、まずスタイル シートでマスター ページのスタイルを AlternateStyles.css 定義します。 に次のルールを AlternateStyles.css追加します。

body 
{
 font-family: Comic Sans MS, Arial; 
 font-size: medium; 
 margin: 0px; 
} 
#topContent 
{ 
 text-align: center; 
 background-color: Navy; 
 color: White; 
 font-size: x-large;
 text-decoration: none; 
 font-weight: bold; 
 padding: 10px; 
 height: 50px;
} 
#topContent a 
{ 
 text-decoration: none; 
 color: White; 
} 
#navContent 
{ 
 font-size: small; 
 text-align: center; 
} 
#footerContent 
{ 
 padding: 10px; 
 font-size: 90%; 
 text-align: center; 
 border-top: solid 1px black; 
} 
#mainContent 
{ 
 text-align: left; 
 padding: 10px;
}

次に、次の宣言型マークアップを に追加します Alternate.master。 ご覧のように、 には、 Alternate.master の ContentPlaceHolder コントロールと同じ ID 値を持つ 4 つの ContentPlaceHolder コントロールが Site.master含まれています。 さらに、ASP.NET AJAX フレームワークを使用する Web サイトのページに必要な ScriptManager コントロールも含まれています。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head id="Head1" runat="server"> 
 <title>Untitled Page</title>
 <asp:ContentPlaceHolder id="head" runat="server">
 </asp:ContentPlaceHolder> 
 <link href="AlternateStyles.css" rel="stylesheet" type="text/css"/> 
</head> 
<body> 
 <form id="form1" runat="server"> 
 <asp:ScriptManager ID="MyManager" runat="server"> 
 </asp:ScriptManager>
 <div id="topContent">
 <asp:HyperLink ID="lnkHome" runat="server" NavigateUrl="~/Default.aspx" 
 Text="Master Pages Tutorials" /> 
 </div>
 <div id="navContent"> 
 <asp:ListView ID="LessonsList" runat="server" 
 DataSourceID="LessonsDataSource">
 <LayoutTemplate>
 <asp:PlaceHolder runat="server" ID="itemPlaceholder" /> 
 </LayoutTemplate>
 <ItemTemplate>
 <asp:HyperLink runat="server" ID="lnkLesson" 
 NavigateUrl='<%# Eval("Url") %>' 
 Text='<%# Eval("Title") %>' /> 
 </ItemTemplate>
 <ItemSeparatorTemplate> | </ItemSeparatorTemplate> 
 </asp:ListView>
 <asp:SiteMapDataSource ID="LessonsDataSource" runat="server" 
 ShowStartingNode="false" /> 
 </div> 
 <div id="mainContent">
 <asp:ContentPlaceHolder id="MainContent" runat="server"> 
 </asp:ContentPlaceHolder>
 </div>
 <div id="footerContent">
 <p> 
 <asp:Label ID="DateDisplay" runat="server"></asp:Label> 
 </p>
 <asp:ContentPlaceHolder ID="QuickLoginUI" runat="server"> 
 </asp:ContentPlaceHolder>
 <asp:ContentPlaceHolder ID="LeftColumnContent" runat="server"> 
 </asp:ContentPlaceHolder>
 </div> 
 </form>
</body> 
</html>

新しいマスター ページのテスト

この新しいマスター ページをテストするには、プロパティにBasePage"~/Alternate.maser"MasterPageFile割り当てられ、Web サイトにアクセスするようにクラスOnPreInitの メソッドを更新します。 と の 2 つ ~/Admin/AddProduct.aspx~/Admin/Products.aspxを除き、すべてのページがエラーなしで機能する必要があります。 で DetailsView ~/Admin/AddProduct.aspx に製品を追加すると NullReferenceException 、マスター ページ GridMessageText の プロパティの設定を試みるコード行から が作成されます。 にアクセス~/Admin/Products.aspxInvalidCastExceptionすると、"型 'ASP.alternate_master' のオブジェクトを型 'ASP.site_master' にキャストできません" というメッセージが表示されたページ読み込み時にスローされます。

これらのエラーは、分離コード クラスに Site.master 、 で定義されていないパブリック イベント、プロパティ、およびメソッドが含まれているために Alternate.master発生します。 これら 2 つのページのマークアップ部分には、マスター ページを @MasterType 参照する ディレクティブがあります Site.master

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

また、 の DetailsView の ItemInserted イベント ハンドラー ~/Admin/AddProduct.aspx には、緩やかに型指定された Page.Master プロパティを 型 Siteのオブジェクトにキャストするコードが含まれています。 @MasterTypeディレクティブ (この方法で使用) とイベント ハンドラーのItemInsertedキャストは、 ページと ~/Admin/Products.aspx ページを~/Admin/AddProduct.aspxマスター ページに密にSite.master結合します。

この緊密な結合を解除するために、パブリック メンバーの定義を含む共通の基底クラスを持ちSite.masterAlternate.master、そこから派生させることができます。 その後、 ディレクティブを更新して、 @MasterType この一般的な基本型を参照できます。

カスタム 基本マスター ページ クラスの作成

という名前BaseMasterPage.vbのフォルダーに新しいクラス ファイルをApp_Code追加し、 からSystem.Web.UI.MasterPage派生させます。 では メソッドと プロパティBaseMasterPageRefreshRecentProductsGridGridMessageText定義する必要がありますが、これらのメンバーはマスター ページ (RecentProductsGridView と GridMessage Label) にSite.master固有の Web コントロールを使用するため、そこから移動Site.masterすることはできません。

必要なのは、これらのメンバーがそこで定義されるように構成BaseMasterPageすることですが、実際には の派生クラス (Site.masterAlternate.master) によってBaseMasterPage実装されます。 この種類の継承は、 クラスを として MustInherit マークし、そのメンバーを として MustOverrideマークすることで可能です。 要するに、これらのキーワードを クラスとその 2 つのメンバーに追加すると、実装されていない RefreshRecentProductsGridGridMessageTextが読み上BaseMasterPageげられるが、その派生クラスは 読み上げられる。

また、 でBaseMasterPageイベントをPricesDoubled定義し、派生クラスによってイベントを発生させる手段を提供する必要があります。 この動作を容易にするために.NET Frameworkで使用されるパターンは、基底クラスにパブリック イベントを作成し、 という名前OnEventNameの保護されたオーバーライド可能なメソッドを追加することです。 その後、派生クラスは、このメソッドを呼び出してイベントを発生させたり、イベントが発生する直前または直後にコードを実行するようにオーバーライドしたりできます。

次のコードが含まれるようにクラスを更新します BaseMasterPage

Public MustInherit Class BaseMasterPage 
 Inherits System.Web.UI.MasterPage 
 Public Event PricesDoubled As EventHandler
 Protected Overridable Sub OnPricesDoubled(ByVal e As EventArgs)
 RaiseEvent PricesDoubled(Me, e)
 End Sub
 Public MustOverride Sub RefreshRecentProductsGrid() 
 Public MustOverride Property GridMessageText() As String 
End Class

次に、分離コード クラスに Site.master 移動し、 から BaseMasterPage派生させます。 にマークされたMustOverrideメンバーが含まれているためBaseMasterPage、 でSite.masterこれらのメンバーをオーバーライドする必要があります。 メソッドとプロパティのOverrides定義にキーワード (keyword)を追加します。 また、基本クラスOnPricesDoubledの メソッドのPricesDoubled呼び出しを使用して、DoublePriceButton のClickイベント ハンドラーでイベントを発生させるコードを更新します。

これらの変更の後、 Site.master 分離コード クラスには次のコードを含める必要があります。

Partial Class Site 
 Inherits BaseMasterPage
 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
 DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd")
 End Sub
 Public Overrides Sub RefreshRecentProductsGrid() 
 RecentProducts.DataBind()
 End Sub 
 Public Overrides Property GridMessageText() As String 
 Get
 Return GridMessage.Text
 End Get 
 Set(ByVal Value As String) 
 GridMessage.Text = Value 
 End Set
 End Property 
 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
 MyBase.OnPricesDoubled(EventArgs.Empty)
 End Sub 
End Class

また、2 つのMustOverrideメンバーからBaseMasterPage派生してオーバーライドするために、 の分離コード クラスを更新Alternate.masterする必要があります。 ただし、最新の製品を一覧表示する GridView や、新しい製品がデータベースに追加された後にメッセージを表示する Label が含まれていないため Alternate.master 、これらのメソッドは何もする必要はありません。

Partial Class Alternate 
 Inherits BaseMasterPage
 Public Overrides Property GridMessageText() As String 
 Get
 Return String.Empty
 End Get
 Set(ByVal value As String) 
 ' Do nothing 
 End Set 
 End Property 
 Public Overrides Sub RefreshRecentProductsGrid()
 ' Do nothing 
 End Sub 
End Class

基本マスター ページ クラスの参照

クラスをBaseMasterPage完了し、2 つのマスター ページを拡張したので、最後の手順では、 ページと ~/Admin/Products.aspx ページを更新~/Admin/AddProduct.aspxして、この一般的な型を参照します。 最初に、両方のページの ディレクティブを @MasterType 次から変更します。

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

移動先:

<%@ MasterType TypeName="BaseMasterPage" %>

プロパティは、ファイル パスを参照するのではなく、 @MasterType 基本型 (BaseMasterPage) を参照するようになりました。 したがって、両方のページの分離コード クラスで使用される厳密に型指定されたMasterプロパティは、型ではなく 型BaseMasterPageSiteになりました。 この変更に伴い、 を再検討してください ~/Admin/Products.aspx。 以前は、ページがマスター ページを使用Alternate.masterするように構成されていますが、 ディレクティブがファイルを参照Site.masterしているため、@MasterTypeキャスト エラーが発生しました。 しかし、ページがエラーなしでレンダリングされるようになりました。 これは、マスター ページを型BaseMasterPageAlternate.masterオブジェクトにキャストできるためです (拡張されているため)。

で行 ~/Admin/AddProduct.aspxう必要がある小さな変更が 1 つあります。 DetailsView コントロールの ItemInserted イベント ハンドラーでは、厳密に型指定されたプロパティと緩やかに型指定された Master プロパティの両方が使用されます Page.Master 。 ディレクティブを更新したときに厳密に型指定された参照を @MasterType 修正しましたが、緩やかに型指定された参照を更新する必要があります。 次のコード行を置き換えます。

Dim myMasterPage As Site = CType(Page.Master, Site)

基本型にキャスト Page.Master する次のを使用します。

Dim myMasterPage As BaseMasterPage = CType(Page.Master, BaseMasterPage)

手順 4: コンテンツ ページにバインドするマスター ページを決定する

現在、このクラスは BasePage 、ページ ライフサイクルの MasterPageFile PreInit ステージで、すべてのコンテンツ ページのプロパティをハードコーディングされた値に設定しています。 このコードを更新して、何らかの外部要素に基づいてマスター ページを作成できます。 読み込むマスター ページは、現在ログオンしているユーザーの設定によって異なる場合があります。 その場合は、 メソッドBasePageOnPreInit、現在アクセスしているユーザーのマスター ページ設定を検索するコードを記述する必要があります。

使用するマスター ページ (またはAlternate.master) をユーザーが選択できる Web ページをSite.master作成し、この選択内容を Session 変数に保存してみましょう。 まず、 という名前 ChooseMasterPage.aspxのルート ディレクトリに新しい Web ページを作成します。 このページ (またはそれ以降の他のコンテンツ ページ) を作成する場合、マスター ページは でプログラムによって設定されるため、マスター ページに BasePageバインドする必要はありません。 ただし、新しいページをマスター ページにバインドしない場合、新しいページの既定の宣言型マークアップには、Web フォームと、マスター ページによって提供されるその他のコンテンツが含まれます。 このマークアップを適切なコンテンツ コントロールに手動で置き換える必要があります。 そのため、新しい ASP.NET ページをマスター ページにバインドする方が簡単です。

注意

Alternate.master には ContentPlaceHolder コントロールのセットが同じであるためSite.master、新しいコンテンツ ページを作成するときに選択するマスター ページは関係ありません。 一貫性を保つには、 を使用 Site.masterすることをお勧めします。

Web サイトに新しいコンテンツ ページを追加する

図 05: Web サイトに新しいコンテンツ ページを追加する (フルサイズの画像を表示する をクリックします)

このレッスンの Web.sitemap エントリを含むようにファイルを更新します。 マスター ページの の下 <siteMapNode> に次のマークアップを追加し、AJAX レッスン ASP.NET します。

<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />

ページにコンテンツを追加するChooseMasterPage.aspx前に、ページの分離コード クラスを (ではなくSystem.Web.UI.Page) からBasePage派生するように更新します。 次に、DropDownList コントロールをページに追加し、そのプロパティを IDMasterPageChoice設定し、"~/Site.master" と "~/Alternate.master" の値を持つ Text 2 つの ListItems を追加します。

Button Web コントロールをページに追加し、その ID プロパティと Text プロパティをそれぞれ SaveLayout に設定し、それぞれ "レイアウトの選択を保存" に設定します。 この時点で、ページの宣言型マークアップは次のようになります。

<p> 
 Your layout choice: 
 <asp:DropDownList ID="MasterPageChoice" runat="server"> 
 <asp:ListItem>~/Site.master</asp:ListItem>
 <asp:ListItem>~/Alternate.master</asp:ListItem>
 </asp:DropDownList> 
</p> 
<p> 
 <asp:Button ID="SaveLayout" runat="server" Text="Save Layout Choice" /> 
</p>

ページに初めてアクセスするときは、ユーザーが現在選択しているマスター ページの選択肢を表示する必要があります。 イベント ハンドラーを Page_Load 作成し、次のコードを追加します。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
 If Not Page.IsPostBack Then 
 If Session("MyMasterPage") IsNot Nothing Then 
 Dim li As ListItem = MasterPageChoice.Items.FindByText(Session("MyMasterPage").ToString())
 If li IsNot Nothing Then 
 li.Selected = True
 End If 
 End If 
 End If 
End Sub

上記のコードは、最初のページ アクセスでのみ実行されます (後続のポストバックでは実行されません)。 最初に、Session 変数 MyMasterPage が存在するかどうかを確認します。 その場合は、DropDownList で一致する ListItem を MasterPageChoice 検索しようとします。 一致する ListItem が見つかった場合、その Selected プロパティは に True設定されます。

また、ユーザーの選択を Session 変数に保存する MyMasterPage コードも必要です。 Button のイベントのイベント ハンドラーを SaveLayout 作成し、次の Click コードを追加します。

Protected Sub SaveLayout_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveLayout.Click 
 Session("MyMasterPage") = MasterPageChoice.SelectedValue 
 Response.Redirect("ChooseMasterPage.aspx")
End Sub

注意

イベント ハンドラーが Click ポストバックで実行される頃には、マスター ページは既に選択されています。 したがって、ユーザーのドロップダウン リストの選択は、次のページにアクセスするまで有効になりません。 は Response.Redirect 、ブラウザーに を強制的に要求 ChooseMasterPage.aspxします。

ページが ChooseMasterPage.aspx 完了したら、最後のタスクは BasePage Session 変数の MasterPageFile 値に基づいて プロパティを MyMasterPage 割り当てることです。 Session 変数が に設定されていない場合、既定値は BasePageSite.master設定されます。

Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
 SetMasterPageFile() 
 MyBase.OnPreInit(e)
End Sub 
Protected Overridable Sub SetMasterPageFile() 
 Me.MasterPageFile = GetMasterPageFileFromSession() 
End Sub 
Protected Function GetMasterPageFileFromSession() As String 
 If Session("MyMasterPage") Is Nothing Then
 Return "~/Site.master"
 Else 
 Return Session("MyMasterPage").ToString() 
 End If 
End Function

注意

オブジェクトMasterPageFileのプロパティを割り当てるコードをPageイベント ハンドラーから OnPreInit 2 つの異なるメソッドに移動しました。 この最初のメソッド は、 SetMasterPageFileプロパティを MasterPageFile 2 番目のメソッド GetMasterPageFileFromSession() によって返される値に割り当てます。 拡張する将来のSetMasterPageFileクラスBasePageが必要に応じてそれをオーバーライドしてカスタム ロジックを実装できるように、 メソッドOverridableをマークしました。 次のチュートリアルでは、 の プロパティをオーバーライドするBasePageSetMasterPageFile例を示します。

このコードを配置した状態で、ページにアクセスします ChooseMasterPage.aspx 。 最初はマスター ページが Site.master 選択されていますが (図 6 を参照)、ユーザーはドロップダウン リストから別のマスター ページを選択できます。

Site.master マスター ページを使用してコンテンツ ページを表示する

図 06: マスター ページを使用してコンテンツ ページが Site.master 表示される (フルサイズの画像を表示するをクリックします)

Alternate.master マスター ページを使用してコンテンツ ページが表示されるようになりました

図 07: マスター ページを使用してコンテンツ ページが Alternate.master 表示されるようになりました (クリックするとフルサイズの画像が表示されます)

まとめ

コンテンツ ページにアクセスすると、そのコンテンツ コントロールはマスター ページの ContentPlaceHolder コントロールと融合されます。 コンテンツ ページのマスター ページは、 クラスの プロパティによってPage示されます。このプロパティは、初期化ステージ中に @Page ディレクティブの MasterPageFile 属性に割り当MasterPageFileてられます。 このチュートリアルで示したように、PreInit ステージの MasterPageFile 終了前であれば、 プロパティに値を割り当てることができます。 プログラムでマスター ページを指定できることで、外部要因に基づいてコンテンツ ページをマスター ページに動的にバインドするなど、より高度なシナリオの扉が開きます。

プログラミングに満足!

もっと読む

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

著者について

複数の 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