動的マスター ページの処理は、一見簡単に見えるかもしれませんが、少し注意が必要です。
次の点を考慮してください。
MasterPage は実際にはページの子コントロールと見なされるため、そのライフサイクルはページ上の他のコントロールと同じです。
実行時に MasterPage を変更するにPreInit
は、ページのイベントで行う必要があります (コントロールにはこのイベントがないため、MasterPage にもこのイベントがないことに注意してください)。
ページのライフ サイクルのPreInit
、Init
、およびLoad
イベントは次のように機能します。ページのPreInit
イベントが発生し、続いInit
てページの子コントロール (MasterPage を含む) のすべてのイベントが発生します。すべての子Init
イベントが発生すると、ページのInit
イベントが発生し、最後にページのInitComplete
イベントが発生して、すべてのInit
イベントが処理されたことを示します。Load
イベントは逆に機能し、ページのイベントLoad
が最初に発生し、次にすべての子コントロールのLoad
イベントが発生し、最後にページのLoadComplete
イベントが発生します。
ページのポスト バックの原因となったポスト バック イベントは、すべての子コントロールのLoad
イベントが発生した後、ページのLoadComplete
イベントの前に発生します。
ページ ViewState へのPreInit
アクセス権がない場合
ソース: http://msdn.microsoft.com/en-us/library/ms178472.aspx
クイックルック:

では、なぜこれが重要なのでしょうか。
あなたの例では3つのボタンがあり、ボタンが押されるたびにMasterPageを変更する必要がありますがPreInit
、ページのイベントでMasterPageを変更する必要がありますが、ボタンハンドラーはその後処理されるため、難しい部分はServer.Transfer
ページを再処理するために呼び出します。
ノート。ユーザーが MasterPage をパーソナライズできるようにするため、ユーザーの設定を保存する方法が必要です。通常は、Cookie またはデータベースを使用します。このサンプルではSession
、簡単にするためにオブジェクトを使用しますが、ニーズに合わせて変更できます。
したがって、これは次のようになります。
マスター ページのコード ビハインド
protected void blueMasterPage_Click(object sender, EventArgs e)
{
this.Session["master"] = "BlueMasterPage";
this.Server.Transfer(this.Request.RawUrl);
}
ページのコードビハインド
protected void Page_PreInit(object sender, EventArgs e)
{
if (this.Session["master"] != null)
{
this.MasterPageFile = string.Format("~/{0}.master", (string)this.Session["master"]);
}
}
注:使用しない場合Server.Transfer
、次にページに投稿するまで、ページの MasterPage への変更は表示されません。
したがって、これはトリッキーでした。私の意見では、同じことをもっと簡単に行うことができるはずです。ASP.Net ページのライフ サイクルはまったく役に立ちません。
サイトに 1 つのマスター ページと異なる CSS レイアウトを使用することに関する @AndreCalil の提案にいつでも従うことができます。
編集 1
言い忘れたことの 1 つは、動的な MasterPage を使用するすべてのページにマスター ページを設定する必要があることです。そのための最善の方法は、ベース ページを作成してそれを継承し、ベース ページに次のように記述することです。PreInit
MasterPage を設定するイベントのコード