動的マスター ページの処理は、一見簡単に見えるかもしれませんが、少し注意が必要です。
次の点を考慮してください。
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 を使用するすべてのページにマスター ページを設定する必要があることです。そのための最善の方法は、ベース ページを作成してそれを継承し、ベース ページに次のように記述することです。PreInitMasterPage を設定するイベントのコード