プログラムでマスター ページを指定する (C#)
PreInit イベント ハンドラーを使用してプログラムでコンテンツ ページのマスター ページを設定する方法について説明します。
はじめに
「 マスター ページを使用した Site-Wide レイアウトの作成」の第 1 の例以降、すべてのコンテンツ ページは ディレクティブの 属性を MasterPageFile
使用して宣言的にマスター ページを @Page
参照しています。 たとえば、次 @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 は、初期コンテンツとマスター ページ コントロール階層を示しています。 PreInit ステージの末尾に、ページ内のコンテンツ コントロールがマスター ページの対応する ContentPlaceHolders に追加されます (手順 2)。 この融合後、マスター ページは、融合されたコントロール階層のルートとして機能します。 その後、この融合コントロール階層がページに追加され、最終的なコントロール階層が生成されます (手順 3)。 結果として、ページのコントロール階層には、融合されたコントロール階層が含まれます。
図 01: PreInit ステージ中にマスター ページとコンテンツ ページのコントロール階層が結合されている (フルサイズの画像を表示する をクリックします)
手順 2: コードからプロパティを設定するMasterPageFile
この融合のマスター ページの部分は、オブジェクトMasterPageFile
の プロパティのPage
値によって異なります。 ディレクティブで 属性をMasterPageFile
@Page
設定すると、ページのライフサイクルの最初のMasterPageFile
ステージである初期化ステージ中に の プロパティを割り当てるPage
という実質的な効果があります。 または、プログラムでこのプロパティを設定することもできます。 ただし、図 1 の融合が行われる前に、このプロパティを設定することが不可欠です。
PreInit ステージの開始時に、オブジェクトはそのイベントをPage
発生させ、そのPreInit
メソッドをOnPreInit
呼び出します。 プログラムでマスター ページを設定するには、イベントのイベント ハンドラー PreInit
を作成するか、 メソッドを OnPreInit
オーバーライドします。 両方のアプローチを見てみましょう。
まず、サイトのホームページの分離コード クラス ファイルを開 Default.aspx.cs
きます。 次のコードを入力して、ページのイベントの PreInit
イベント ハンドラーを追加します。
protected void Page_PreInit(object sender, EventArgs e)
{
}
ここから、 プロパティを MasterPageFile
設定できます。 値 "~/Site.master" を プロパティに割り当てるようにコードを MasterPageFile
更新します。
protected void Page_PreInit(object sender, EventArgs e)
{
this.MasterPageFile = "~/Site.master";
}
ブレークポイントを設定してデバッグを開始すると、ページにアクセスするたびにDefault.aspx
、またはこのページへのポストバックが発生するたびに、イベント ハンドラーが実行されMasterPageFile
、Page_PreInit
プロパティが "~/Site.master" に割り当てられます。
または、クラスの OnPreInit
メソッドをPage
オーバーライドし、そこで プロパティをMasterPageFile
設定することもできます。 この例では、マスター ページを特定のページに設定するのではなく、 から BasePage
設定してみましょう。 マスター ページのチュートリアルの「タイトル、メタ タグ、およびその他の HTML ヘッダーの指定」でカスタム基本ページ クラス (BasePage
) を作成したことを思い出してください。 現在BasePage
、クラスの OnLoadComplete
メソッドをPage
オーバーライドし、サイト マップ データに基づいてページのTitle
プロパティを設定します。 を 更新 BasePage
して、 メソッドを OnPreInit
オーバーライドして、プログラムによってマスター ページを指定しましょう。
protected override void OnPreInit(EventArgs e)
{
this.MasterPageFile = "~/Site.master";
base.OnPreInit(e);
}
すべてのコンテンツ ページは から BasePage
派生しているため、すべてのコンテンツ ページにプログラムによってマスター ページが割り当てられるようになりました。 この時点で、 のPreInit
Default.aspx.cs
イベント ハンドラーは余分です。自由に削除してください。
ディレクティブについて@Page
少しわかりにくいのは、コンテンツ ページのMasterPageFile
プロパティが 2 つの場所で指定されていることです。クラスの OnPreInit
メソッドでBasePage
プログラムを使用する方法と、各コンテンツ ページの @Page
ディレクティブの 属性を使用MasterPageFile
する方法です。
ページ ライフサイクルの最初のステージは、初期化ステージです。 この段階では、Page
オブジェクトの MasterPageFile
プロパティに ディレクティブ内@Page
の 属性のMasterPageFile
値が割り当てられます (指定されている場合)。 PreInit ステージは初期化ステージに従い、ここでプログラムでオブジェクトの MasterPageFile
プロパティをPage
設定し、 ディレクティブから割り当てられた値を@Page
上書きします。 オブジェクトの プロパティを Page
プログラムで設定しているため、エンド ユーザーの MasterPageFile
エクスペリエンスに MasterPageFile
影響を与えることなく、 ディレクティブから @Page
属性を削除できます。 これを理解するには、 内の ディレクティブDefault.aspx
から 属性をMasterPageFile
@Page
削除し、ブラウザーからページにアクセスします。 予想どおり、出力は 属性が削除される前と同じです。
プロパティが ディレクティブを MasterPageFile
使用して @Page
設定されているか、プログラムによって設定されるかは、エンド ユーザーのエクスペリエンスに関係なく行われます。 ただし、 ディレクティブの MasterPageFile
@Page
属性は、デザイン時に Visual Studio によって使用され、Designerで WYSIWYG ビューが生成されます。 Visual Studio で にDefault.aspx
戻り、Designerに移動すると、"マスター ページ エラー: ページにはマスター ページ参照を必要とするコントロールがありますが、何も指定されていない" というメッセージが表示されます (図 2 を参照)。
つまり、Visual Studio で豊富なデザイン時エクスペリエンスを@Page
実現するには、 ディレクティブに 属性を残すMasterPageFile
必要があります。
@Page ディレクティブの MasterPageFile 属性を使用してデザイン ビューをレンダリングします" />
図 02: Visual Studio は ディレクティブの MasterPageFile
属性を@Page
使用してデザイン ビューをレンダリングします (フルサイズの画像を表示する場合はクリックします)
手順 3: 代替マスター ページを作成する
コンテンツ ページのマスター ページは実行時にプログラムで設定できるため、外部条件に基づいて特定のマスター ページを動的に読み込むことができます。 この機能は、サイトのレイアウトがユーザーによって異なる必要がある状況で役立ちます。 たとえば、ブログ エンジン Web アプリケーションでは、各レイアウトが異なるマスター ページに関連付けられているブログのレイアウトをユーザーが選択できる場合があります。 実行時に、訪問者がユーザーのブログを表示している場合、Web アプリケーションはブログのレイアウトを決定し、対応するマスター ページをコンテンツ ページに動的に関連付ける必要があります。
いくつかの外部条件に基づいて、実行時にマスター ページを動的に読み込む方法を見てみましょう。 現在、この Web サイトにはマスター ページSite.master
() が 1 つだけ含まれています。 実行時にマスター ページを選択する方法を示すために、別のマスター ページが必要です。 この手順では、新しいマスター ページの作成と構成に焦点を当てます。 手順 4 では、実行時に使用するマスター ページを決定する方法について説明します。
という名前 Alternate.master
のルート フォルダーに新しいマスター ページを作成します。 また、 という名前 AlternateStyles.css
の Web サイトに新しいスタイル シートを追加します。
図 03: Web サイトに別のマスター ページと CSS ファイルを追加する (フルサイズの画像を表示する をクリックします)
マスター ページを Alternate.master
デザインして、タイトルがページの上部に表示され、中央に配置され、海軍の背景に表示されるようにしました。 左側の列を調べ、そのコンテンツを ContentPlaceHolder コントロールの下 MainContent
に移動しました。これはページの幅全体にまたがっています。 さらに、順序付けられていないレッスンリストを作成し、上 MainContent
の水平リストに置き換えました。 また、マスター ページで使用されるフォントと色も更新しました (また、拡張によって、そのコンテンツ ページ)。 図 4 は、マスター ページを使用する場合をAlternate.master
示していますDefault.aspx
。
注意
ASP.NET には 、テーマを定義する機能が含まれています。 Theme は、実行時にページに適用できる画像、CSS ファイル、およびスタイル関連の Web コントロール プロパティ設定のコレクションです。 テーマは、サイトのレイアウトが表示される画像と CSS ルールによってのみ異なる場合に行く方法です。 異なる Web コントロールの使用や、レイアウトが大幅に異なるなど、レイアウトが大幅に異なる場合は、個別のマスター ページを使用する必要があります。 テーマの詳細については、このチュートリアルの最後にある「さらに読む」セクションを参照してください。
図 04: コンテンツ ページで新しい外観を使用できるようになりました (クリックするとフルサイズの画像が表示されます)
マスター ページとコンテンツ ページのマークアップが融合されると、 MasterPage
クラスは、コンテンツ ページ内のすべてのコンテンツ コントロールがマスター ページの ContentPlaceHolder を参照していることを確認します。 存在しない ContentPlaceHolder を参照する Content コントロールが見つかった場合、例外がスローされます。 言い換えると、コンテンツ ページに割り当てられているマスター ページには、コンテンツ ページ内のコンテンツ コントロールごとに ContentPlaceHolder が必要です。
Site.master
マスター ページには、次の 4 つの ContentPlaceHolder コントロールが含まれています。
head
MainContent
QuickLoginUI
LeftColumnContent
当社のウェブサイトのコンテンツページの一部には、1つまたは2つのコンテンツコントロールが含まれています。他のユーザーには、使用可能な各 ContentPlaceHolders の Content コントロールが含まれます。 すべての ContentPlaceHolders Site.master
のコンテンツ コントロールを持つコンテンツ ページに新しいマスター ページ (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.master" が割り当てるようにMasterPageFile
クラスのOnPreInit
メソッドを更新し、Web サイトにアクセスします。 と の 2 つ ~/Admin/AddProduct.aspx
~/Admin/Products.aspx
を除き、すべてのページがエラーなしで機能する必要があります。 で DetailsView ~/Admin/AddProduct.aspx
に製品を追加すると NullReferenceException
、マスター ページ GridMessageText
の プロパティの設定を試みるコード行から が作成されます。 にアクセス~/Admin/Products.aspx
InvalidCastException
すると、"型 '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.master
Alternate.master
、そこから派生させることができます。 その後、 ディレクティブを更新して、 @MasterType
この一般的な基本型を参照できます。
カスタム 基本マスター ページ クラスの作成
という名前BaseMasterPage.cs
のフォルダーに新しいクラス ファイルをApp_Code
追加し、 からSystem.Web.UI.MasterPage
派生させます。 では メソッドと プロパティBaseMasterPage
をRefreshRecentProductsGrid
GridMessageText
定義する必要がありますが、これらのメンバーはマスター ページ (RecentProducts
GridView と GridMessage
Label) にSite.master
固有の Web コントロールを使用するため、そこから移動Site.master
することはできません。
必要なのは、これらのメンバーがそこで定義されるように構成BaseMasterPage
することですが、実際には の派生クラス (Site.master
と Alternate.master
) によってBaseMasterPage
実装されます。 この種類の継承は、 クラスとそのメンバーを として abstract
マークすることで可能です。 要するにabstract
、これら 2 つのメンバーにキーワード (keyword)を追加すると、実装されていない RefreshRecentProductsGrid
と GridMessageText
が読み上BaseMasterPage
げられるが、その派生クラスは と読み上げられる。
また、 でBaseMasterPage
イベントをPricesDoubled
定義し、派生クラスによってイベントを発生させる手段を提供する必要があります。 この動作を容易にするために.NET Frameworkで使用されるパターンは、基底クラスにパブリック イベントを作成し、 virtual
という名前OnEventName
の保護されたメソッドを追加することです。 その後、派生クラスは、このメソッドを呼び出してイベントを発生させたり、イベントが発生する直前または直後にコードを実行するようにオーバーライドしたりできます。
次のコードが含まれるようにクラスを更新します BaseMasterPage
。
using System; public abstract class BaseMasterPage : System.Web.UI.MasterPage
{
public event EventHandler PricesDoubled;
protected virtual void OnPricesDoubled(EventArgs e)
{
if (PricesDoubled != null)
PricesDoubled(this, e);
}
public abstract void RefreshRecentProductsGrid();
public abstract string GridMessageText
{
get;
set;
}
}
次に、分離コード クラスに Site.master
移動し、 から BaseMasterPage
派生させます。 では、 abstract
でSite.master
これらのabstract
メンバーをオーバーライドする必要があるためBaseMasterPage
です。 メソッドとプロパティのoverride
定義にキーワード (keyword)を追加します。 また、基本クラスOnPricesDoubled
の メソッドのPricesDoubled
呼び出しを使用して、DoublePrice
Button のClick
イベント ハンドラーでイベントを発生させるコードを更新します。
これらの変更の後、 Site.master
分離コード クラスには次のコードを含める必要があります。
public partial class Site : BaseMasterPage {
protected void Page_Load(object sender, EventArgs e)
{
DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd");
}
public override void RefreshRecentProductsGrid()
{
RecentProducts.DataBind();
}
public override string GridMessageText
{
get
{
return GridMessage.Text;
}
set
{
GridMessage.Text = value;
}
}
protected void DoublePrice_Click(object sender, EventArgs e)
{
// Double the prices
DoublePricesDataSource.Update();
// Refresh RecentProducts
RecentProducts.DataBind();
// Raise the PricesDoubled event
base.OnPricesDoubled(EventArgs.Empty);
}
}
また、2 つのabstract
メンバーからBaseMasterPage
派生してオーバーライドするために、 の分離コード クラスを更新Alternate.master
する必要があります。 ただし、最新の製品を一覧表示する GridView や、新しい製品がデータベースに追加された後にメッセージを表示する Label が含まれていないため Alternate.master
、これらのメソッドは何もする必要はありません。
public partial class Alternate : BaseMasterPage
{
public override void RefreshRecentProductsGrid()
{
// Do nothing
}
public override string GridMessageText
{
get
{
return string.Empty;
}
set
{
// Do nothing
}
}
}
基本マスター ページ クラスの参照
クラスをBaseMasterPage
完了し、2 つのマスター ページを拡張したので、最後の手順では、 ページと ~/Admin/Products.aspx
ページを更新~/Admin/AddProduct.aspx
して、この一般的な型を参照します。 最初に、両方のページの ディレクティブを @MasterType
次から変更します。
<%@ MasterType VirtualPath="~/Site.master" %>
移動先:
<%@ MasterType TypeName="BaseMasterPage" %>
プロパティは、ファイル パスを参照するのではなく、 @MasterType
基本型 (BaseMasterPage
) を参照するようになりました。 したがって、両方のページの分離コード クラスで使用される厳密に型指定されたMaster
プロパティは、型ではなく 型BaseMasterPage
Site
になりました。 この変更に伴い、 を再検討してください ~/Admin/Products.aspx
。 以前は、ページがマスター ページを使用Alternate.master
するように構成されていますが、 ディレクティブがファイルを参照Site.master
しているため、@MasterType
キャスト エラーが発生しました。 しかし、ページがエラーなしでレンダリングされるようになりました。 これは、マスター ページを型BaseMasterPage
のAlternate.master
オブジェクトにキャストできるためです (拡張されているため)。
で行 ~/Admin/AddProduct.aspx
う必要がある小さな変更が 1 つあります。 DetailsView コントロールの ItemInserted
イベント ハンドラーでは、厳密に型指定されたプロパティと緩やかに型指定された Master
プロパティの両方が使用されます Page.Master
。 ディレクティブを更新したときに厳密に型指定された参照を @MasterType
修正しましたが、緩やかに型指定された参照を更新する必要があります。 次のコード行を置き換えます。
Site myMasterPage = Page.Master as Site;
基本型にキャスト Page.Master
する次のを使用します。
BaseMasterPage myMasterPage = Page.Master as BaseMasterPage;
手順 4: コンテンツ ページにバインドするマスター ページを決定する
現在、このクラスは BasePage
、ページ ライフサイクルの MasterPageFile
PreInit ステージで、すべてのコンテンツ ページのプロパティをハードコーディングされた値に設定しています。 このコードを更新して、何らかの外部要素に基づいてマスター ページを作成できます。 読み込むマスター ページは、現在ログオンしているユーザーの設定によって異なる場合があります。 その場合は、 メソッドBasePage
でOnPreInit
、現在アクセスしているユーザーのマスター ページ設定を検索するコードを記述する必要があります。
使用するマスター ページ (またはAlternate.master
) をユーザーが選択できる Web ページをSite.master
作成し、この選択内容を Session 変数に保存してみましょう。 まず、 という名前 ChooseMasterPage.aspx
のルート ディレクトリに新しい Web ページを作成します。 このページ (またはそれ以降の他のコンテンツ ページ) を作成する場合、マスター ページは でプログラムによって設定されるため、マスター ページに BasePage
バインドする必要はありません。 ただし、新しいページをマスター ページにバインドしない場合、新しいページの既定の宣言型マークアップには、Web フォームと、マスター ページによって提供されるその他のコンテンツが含まれます。 このマークアップを適切なコンテンツ コントロールに手動で置き換える必要があります。 そのため、新しい ASP.NET ページをマスター ページにバインドする方が簡単です。
注意
と Alternate.master
には ContentPlaceHolder コントロールのセットが同じであるためSite.master
、新しいコンテンツ ページを作成するときに選択するマスター ページは関係ありません。 一貫性を保つには、 を使用 Site.master
することをお勧めします。
図 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 コントロールをページに追加し、そのプロパティを ID
に MasterPageChoice
設定し、"~/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 void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["MyMasterPage"] != null)
{
ListItem li = MasterPageChoice.Items.FindByText(Session["MyMasterPage"].ToString());
if (li != null)
li.Selected = true;
}
}
}
上記のコードは、最初のページ アクセスでのみ実行されます (後続のポストバックでは実行されません)。 最初に、Session 変数 MyMasterPage
が存在するかどうかを確認します。 その場合は、DropDownList で一致する ListItem を MasterPageChoice
検索しようとします。 一致する ListItem が見つかった場合、その Selected
プロパティは に true
設定されます。
また、ユーザーの選択を Session 変数に保存する MyMasterPage
コードも必要です。 Button のイベントのイベント ハンドラーを SaveLayout
作成し、次の Click
コードを追加します。
protected void SaveLayout_Click(object sender, EventArgs e)
{
Session["MyMasterPage"] = MasterPageChoice.SelectedValue;
Response.Redirect("ChooseMasterPage.aspx");
}
注意
イベント ハンドラーが Click
ポストバックで実行される頃には、マスター ページは既に選択されています。 したがって、ユーザーのドロップダウン リストの選択は、次のページにアクセスするまで有効になりません。 は Response.Redirect
、ブラウザーに を強制的に要求 ChooseMasterPage.aspx
します。
ページが ChooseMasterPage.aspx
完了したら、最後のタスクは BasePage
Session 変数の MasterPageFile
値に基づいて プロパティを MyMasterPage
割り当てることです。 Session 変数が に設定されていない場合、既定値は BasePage
に Site.master
設定されます。
protected override void OnPreInit(EventArgs e)
{
SetMasterPageFile();
base.OnPreInit(e);
}
protected virtual void SetMasterPageFile()
{
this.MasterPageFile = GetMasterPageFileFromSession();
}
protected string GetMasterPageFileFromSession()
{
if (Session["MyMasterPage"] == null)
return "~/Site.master";
else
return Session["MyMasterPage"].ToString();
}
注意
オブジェクトMasterPageFile
のプロパティを割り当てるコードをPage
イベント ハンドラーから OnPreInit
2 つの異なるメソッドに移動しました。 この最初のメソッド は、 SetMasterPageFile
プロパティを MasterPageFile
2 番目のメソッド GetMasterPageFileFromSession
() によって返される値に割り当てます。 必要に応じて、拡張する将来のSetMasterPageFile
クラスがBasePage
必要に応じてそれをオーバーライドしてカスタム ロジックを実装できるように、 メソッドvirtual
を作成しました。 次のチュートリアルでは、 の プロパティをオーバーライドするBasePage
SetMasterPageFile
例を示します。
このコードを配置した状態で、ページにアクセスします ChooseMasterPage.aspx
。 最初はマスター ページが Site.master
選択されていますが (図 6 を参照)、ユーザーはドロップダウン リストから別のマスター ページを選択できます。
図 06: マスター ページを使用してコンテンツ ページが Site.master
表示される (フルサイズの画像を表示するをクリックします)
図 07: マスター ページを使用してコンテンツ ページが Alternate.master
表示されるようになりました (クリックするとフルサイズの画像が表示されます)
まとめ
コンテンツ ページにアクセスすると、そのコンテンツ コントロールはマスター ページの ContentPlaceHolder コントロールと融合されます。 コンテンツ ページのマスター ページは、 クラスの プロパティによってPage
示されます。このプロパティは、初期化ステージ中に @Page
ディレクティブの MasterPageFile
属性に割り当MasterPageFile
てられます。 このチュートリアルで示したように、PreInit ステージの MasterPageFile
終了前であれば、 プロパティに値を割り当てることができます。 プログラムでマスター ページを指定できることで、外部要因に基づいてコンテンツ ページをマスター ページに動的にバインドするなど、より高度なシナリオの扉が開きます。
プログラミングに満足!
もっと読む
このチュートリアルで説明するトピックの詳細については、次のリソースを参照してください。
- ASP.NET ページのライフサイクル図
- ASP.NET ページのライフサイクルの概要
- ASP.NET テーマとスキンの概要
- マスター ページ: ヒント、テクニック、トラップ
- ASP.NET のテーマ
著者について
複数の 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
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示