次の方法で共有


複数の ContentPlaceHolders と既定のコンテンツ (VB)

作成者: Scott Mitchell

PDF のダウンロード

マスター ページに複数のコンテンツ プレース ホルダーを追加する方法と、コンテンツ プレース ホルダーに既定のコンテンツを指定する方法について説明します。

はじめに

前のチュートリアルでは、マスター ページを使用して、ASP.NET 開発者がサイト全体の一貫性のあるレイアウトを作成できるようにする方法について説明しました。 マスター ページでは、すべてのコンテンツ ページに共通するマークアップと、ページ単位でカスタマイズ可能な領域の両方を定義します。 前のチュートリアルでは、単純なマスター ページ (Site.master) と 2 つのコンテンツ ページ (Default.aspx および About.aspx) を作成しました。 マスター ページは、head および MainContent という名前の 2 つの ContentPlaceHolder で構成され、それぞれ <head> 要素と Web フォームに配置されていました。 コンテンツ ページにはそれぞれ 2 つのコンテンツ コントロールがありましたが、MainContent に対応する 1 つに対してのみマークアップを指定しました。

Site.master の 2 つの ContentPlaceHolder コントロールが示すように、マスター ページには複数の ContentPlaceHolder が含まれる場合があります。 さらに、マスター ページでは、ContentPlaceHolder コントロールの既定のマークアップを指定できます。 コンテンツ ページでは、必要に応じて独自のマークアップを指定したり、既定のマークアップを使用したりできます。 このチュートリアルでは、マスター ページで複数のコンテンツ コントロールを使用し、ContentPlaceHolder コントロールで既定のマークアップを定義する方法について説明します。

ステップ 1: マスター ページに追加の ContentPlaceHolder コントロールを追加する

多くの Web サイト デザインには、ページ単位でカスタマイズされるいくつかの領域が画面に含まれています。 Site.master (前のチュートリアルで作成したマスター ページ) には、Web フォーム内に MainContent という名前の 1 つの ContentPlaceHolder が含まれています。 具体的には、この ContentPlaceHolder は mainContent <div> 要素内にあります。

図 1 は、ブラウザーで表示した場合の Default.aspx を示しています。 赤で囲まれている領域は、MainContent に対応するページ固有のマークアップです。

円で囲まれている領域には、現在カスタマイズ可能な領域がページ単位で表示されます

図 01: 円で囲まれている領域は、ページ単位で現在カスタマイズ可能な領域を示している (クリックするとフルサイズの画像が表示されます)

図 1 に示した領域に加えて、左側の列の [Lessons] および [News] セクションの下にページ固有の項目を追加する必要もあるとしましょう。 これを実現するために、別の ContentPlaceHolder コントロールをマスター ページに追加します。 作業を進めるために、Visual Web Developer で Site.master マスター ページを開き、[News] セクションの後のデザイナーにツールボックスから ContentPlaceHolder コントロールをドラッグします。 ContentPlaceHolder の IDLeftColumnContent に設定します。

マスター ページの左列に ContentPlaceHolder コントロールを追加する

図 02: マスター ページの左側の列に ContentPlaceHolder コントロールを追加する (クリックするとフルサイズの画像が表示されます)

マスター ページに LeftColumnContent ContentPlaceHolder を追加すると、ContentPlaceHolderIDLeftColumnContent に設定されているページにコンテンツ コントロールを含めることで、この領域のコンテンツをページ単位で定義できます。 このプロセスは、ステップ 2 で確認します。

ステップ 2: コンテンツ ページで新しい ContentPlaceHolder のコンテンツを定義する

Web サイトに新しいコンテンツ ページを追加すると、Visual Web Developer によって、選択したマスター ページの各 ContentPlaceHolder のページにコンテンツ コントロールが自動的に作成されます。 ステップ 1 のマスター ページに LeftColumnContent ContentPlaceHolder を追加すると、新しい ASP.NET ページに 3 つのコンテンツ コントロールが追加されます。

これを説明するために、Site.master マスター ページにバインドされている MultipleContentPlaceHolders.aspx という名前の新しいコンテンツ ページをルート ディレクトリに追加します。 Visual Web Developer は、次の宣言型マークアップを使用してこのページを作成します。

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="MultipleContentPlaceHolders.aspx.vb" Inherits="MultipleContentPlaceHolders" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="LeftColumnContent" Runat="Server">
</asp:Content>

MainContent ContentPlaceHolder を参照しているコンテンツ コントロール (Content2) にコンテンツを入力します。 次に、Content3 コンテンツ コントロール (これは LeftColumnContent ContentPlaceHolder を参照しています) に次のマークアップを追加します。

<h3>Page-Specific Content</h3>
<ul>
 <li>This content is defined in the content page.</li>
 <li>The master page has two regions in the Web Form that are editable on a
 page-by-page basis.</li>
</ul>

このマークアップを追加した後、ブラウザーを使用してページにアクセスします。 図 3 に示すように、Content3 コンテンツ コントロールに配置されたマークアップは、[News] セクションの下の左側の列に表示されます (赤で囲まれています)。 Content2 に配置されたマークアップは、ページの右側に表示されます (青で囲まれています)。

左側の列に、ニュース セクションの下にページ固有のコンテンツが含まれるようになりました

図 03: 左側の列の [News] セクションの下にページ固有のコンテンツが含まれている (クリックするとフルサイズの画像が表示されます)

既存のコンテンツ ページでのコンテンツの定義

新しいコンテンツ ページを作成すると、ステップ 1 で追加した ContentPlaceHolder コントロールが自動的に組み込まれます。 ただし、既存の 2 つのコンテンツ ページ About.aspxDefault.aspx には、LeftColumnContent ContentPlaceHolder のコンテンツ コントロールはありません。 これら 2 つの既存のページでこの ContentPlaceHolder のコンテンツを指定するには、コンテンツ コントロールを自分で追加する必要があります。

ほとんどの ASP.NET Web コントロールとは異なり、Visual Web Developer ツールボックスにはコンテンツ コントロール項目は含まれません。 コンテンツ コントロールの宣言型マークアップをソース ビューに手動で入力できますが、デザイン ビューを使用する方が簡単かつ迅速なアプローチです。 About.aspx ページを開き、デザイン ビューに切り替えます。 図 4 に示すように、LeftColumnContent ContentPlaceHolder がデザイン ビューに表示されます。そこにマウスを置くと、タイトルに "LeftColumnContent (Master)" と表示されます。タイトルに "Master" が含まれていることは、この ContentPlaceHolder のページにコンテンツ コントロールが定義されていないことを示します。 ContentPlaceHolder のコンテンツ コントロールが存在する場合は、MainContent の場合と同様に、タイトルは "ContentPlaceHolderID (Custom)" となります。

LeftColumnContent ContentPlaceHolder のコンテンツ コントロールを About.aspx に追加するには、ContentPlaceHolder のスマート タグを展開し、[カスタム コンテンツの作成] リンクを選択します。

About.aspxのデザイン ビューに LeftColumnContent ContentPlaceHolder が表示される

図 04: About.aspx のデザイン ビューは LeftColumnContent ContentPlaceHolder を示している (クリックするとフルサイズの画像が表示されます)

[カスタム コンテンツの作成] リンクを選択すると、ページに必要なコンテンツ コントロールが生成され、その ContentPlaceHolderID プロパティが ContentPlaceHolder の ID に設定されます。 たとえば、About.aspxLeftColumnContent 領域の [カスタム コンテンツの作成] リンクを選択すると、次の宣言型マークアップがページに追加されます。

<asp:Content ID="Content3" runat="server" 
 contentplaceholderid="LeftColumnContent">
 
</asp:Content>

コンテンツ コントロールの省略

ASP.NET では、マスター ページで定義されているすべての ContentPlaceHolder のコンテンツ コントロールがすべてのコンテンツ ページに含まれている必要はありません。 コンテンツ コントロールを省略すると、ASP.NET エンジンはマスター ページ内の ContentPlaceHolder 内で定義されたマークアップを使用します。 このマークアップは ContentPlaceHolder の "既定のコンテンツ" と呼ばれ、一部の領域のコンテンツがページの大部分では共通であるものの、少数のページでカスタマイズする必要があるシナリオで役立ちます。 ステップ 3 では、マスター ページの既定のコンテンツを指定します。

現在、Default.aspx には head および MainContent ContentPlaceHolder 用の 2 つのコンテンツ コントロールが含まれています。LeftColumnContent 用のコンテンツ コントロールはありません。 その結果、Default.aspx のレンダリング時に LeftColumnContent ContentPlaceHolder の既定のコンテンツが使用されます。 この ContentPlaceHolder の既定のコンテンツはまだ定義していないため、この領域に対してマークアップが出力されないことが最終的な結果になります。 この動作を確認するには、ブラウザーから Default.aspx にアクセスします。 図 5 に示すように、[News] セクションの下の左側の列にはマークアップが出力されません。

LeftColumnContent ContentPlaceHolder に対してコンテンツがレンダリングされない

図 05: LeftColumnContent ContentPlaceHolder のコンテンツはレンダリングされていない (クリックするとフルサイズの画像が表示されます)

ステップ 3: マスター ページの既定のコンテンツを指定する

一部の Web サイト デザインには、1 つか 2 つの例外を除き、サイト内のすべてのページでコンテンツが同じである領域が含まれます。 ユーザー アカウントをサポートする Web サイトについて考えてみましょう。 このようなサイトには、訪問者がサイトにサインインするための資格情報を入力できるログイン ページが必要です。 サインイン プロセスを迅速化するために、Web サイト デザイナーは、ユーザーがログイン ページに明示的にアクセスしなくてもサインインできるように、すべてのページの左上隅にユーザー名とパスワードのテキスト ボックスを含めることができます。 これらのユーザー名とパスワードのテキスト ボックスはほとんどのページで役立ちますが、ユーザーの資格情報のテキスト ボックスが既に含まれているログイン ページでは冗長です。

このデザインを実装するには、マスター ページの左上隅に ContentPlaceHolder コントロールを作成します。 左上隅にユーザー名とパスワードのテキスト ボックスを表示する必要がある各ページでは、この ContentPlaceHolder のコンテンツ コントロールを作成し、必要なインターフェイスを追加します。 一方、ログイン ページでは、この ContentPlaceHolder のコンテンツ コントロールの追加を省略するか、マークアップが定義されていないコンテンツ コントロールを作成します。 この方法の欠点は、サイトに追加するすべてのページ (ログイン ページを除く) にユーザー名とパスワードのテキスト ボックスを忘れずに追加する必要があることです。 これはトラブルの基になります。 これらのテキスト ボックスを 1 つか 2 つのページに追加することを忘れる可能性があります。または、さらに悪いことに、インターフェイスを正しく実装しない可能性があります (2 つではなく 1 つのテキスト ボックスのみを追加するなど)。

より適切な解決策は、ユーザー名とパスワードのテキスト ボックスを ContentPlaceHolder の既定のコンテンツとして定義することです。 これにより、ユーザー名とパスワードのテキスト ボックスを表示しない少数のページ (ログイン ページなど) でのみ、この既定のコンテンツをオーバーライドすることが必要になります。 ContentPlaceHolder コントロールの既定のコンテンツを指定する方法を説明するために、先ほど説明したシナリオを実装しましょう。

Note

このチュートリアルの以降の部分では、ログイン ページ以外のすべてのページの左側の列にログイン インターフェイスを含むように Web サイトを更新します。 ただし、このチュートリアルでは、ユーザー アカウントをサポートするように Web サイトを構成する方法については説明しません。 このトピックの詳細については、フォーム認証、承認、ユーザー アカウント、ロールに関するチュートリアルを参照してください。

ContentPlaceHolder の追加とその既定のコンテンツの指定

Site.master マスター ページを開き、左側の列の DateDisplay の [Label] と [Lessons] のセクション間に次のマークアップを追加します。

<asp:ContentPlaceHolder ID="QuickLoginUI" runat="server">
 <asp:Login ID="QuickLogin" runat="server" 
    TitleText="<h3>Sign In</h3>"
    FailureAction="RedirectToLoginPage">
 </asp:Login>
</asp:ContentPlaceHolder>

このマークアップを追加すると、マスター ページのデザイン ビューは図 6 のようになります。

マスター ページにログイン コントロールが含まれている

図 06: マスター ページにログイン コントロールが含まれている (クリックするとフルサイズの画像が表示されます)

この ContentPlaceHolder (QuickLoginUI) には、既定のコンテンツとしてログイン Web コントロールがあります。 ログイン コントロールでは、ユーザーにユーザー名とパスワードの入力を求めるユーザー インターフェイスが [ログイン] ボタンと共に表示されます。 [ログイン] ボタンを選択すると、ログイン コントロールは、Membership API に対してユーザーの資格情報を内部的に検証します。 このログイン コントロールを実際に使用するには、Membership を使用するようにサイトを構成する必要があります。 このトピックは、このチュートリアルの範囲外です。ユーザー アカウントをサポートする Web アプリケーションの構築の詳細については、フォーム認証、承認、ユーザー アカウント、ロールに関するチュートリアルを参照してください。

ログイン コントロールの動作や外観は自由にカスタマイズできます。 そのプロパティのうち 2 つ (TitleTextFailureAction) を設定しました。 TitleText プロパティ値 (既定値は "ログイン") は、コントロールのユーザー インターフェイスの上部に表示されます。 "Sign In" というテキストを <h3> 要素として表示するようにこのプロパティを設定しました。 FailureAction プロパティは、ユーザーの資格情報が無効な場合の処理を示します。 既定値は Refresh で、ユーザーを同じページに残し、ログイン コントロール内にエラー メッセージを表示します。 これを RedirectToLoginPage に変更しました。これは、資格情報が無効な場合にユーザーをログイン ページに送ります。 ユーザーが他のページからログインしようとした場合にユーザーをログイン ページに送るのが望ましいのですが、ログイン ページには左側の列に簡単に収まらない追加の指示とオプションが含まれている可能性があるため、失敗します。 たとえば、ログイン ページには、忘れたパスワードを取得したり、新しいアカウントを作成したりするオプションが含まれている場合があります。

ログイン ページの作成と既定のコンテンツのオーバーライド

マスター ページが完成したら、次の手順はログイン ページの作成です。 ASP.NET ページを Login.aspx という名前のサイトのルート ディレクトリに追加し、Site.master マスター ページにバインドします。 これにより、4 つのコンテンツ コントロールを含むページが作成されます。Site.master で定義されている ContentPlaceHolder ごとに 1 つです。

MainContent コンテンツ コントロールにログイン コントロールを追加します。 同様に、任意のコンテンツを LeftColumnContent 領域に自由に追加できます。 ただし、QuickLoginUI ContentPlaceHolder のコンテンツ コントロールは必ず空のままにしてください。 これにより、ログイン ページの左側の列にログイン コントロールが表示されなくなります。

MainContent および LeftColumnContent 領域のコンテンツを定義すると、ログイン ページの宣言型マークアップは次のようになります。

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Login.aspx.vb" Inherits="Login" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
 <h2>
 Sign In</h2>
 <p>
 <asp:Login ID="Login1" runat="server" TitleText="">
 </asp:Login>
 </p>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="QuickLoginUI" Runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="LeftColumnContent" Runat="Server">
 <h3>Sign In Tasks</h3>
 <ul>
 <li>Create a New Account</li>
 <li>Recover Forgotten Password</li>
 </ul>
 <p>TODO: Turn the above text into links...</p>
</asp:Content>

図 7 は、ブラウザーで表示された場合のこのページを示しています。 このページは QuickLoginUI ContentPlaceHolder のコンテンツ コントロールを指定するため、マスター ページで指定された既定のコンテンツをオーバーライドします。 最終的な効果は、このページに、マスター ページのデザイン ビュー (図 6 を参照) に表示されるログイン コントロールがレンダリングされないことです。

ログイン ページは、QuickLoginUI ContentPlaceHolder の既定のコンテンツを抑制します

図 07: ログイン ページは、QuickLoginUI ContentPlaceHolder の既定のコンテンツを抑制する (クリックするとフルサイズの画像が表示されます)

新しいページでの既定のコンテンツの使用

ログイン ページを除くすべてのページの左側の列にログイン コントロールを表示します。 これを実現するには、ログイン ページを除くすべてのコンテンツ ページで、QuickLoginUI ContentPlaceHolder のコンテンツ コントロールを省略する必要があります。 コンテンツ コントロールを省略すると、ContentPlaceHolder の既定のコンテンツが代わりに使用されます。

既存のコンテンツ ページ (Default.aspxAbout.aspxMultipleContentPlaceHolders.aspx) には、QuickLoginUI のコンテンツ コントロールは含まれません。これらは、ContentPlaceHolder コントロールをマスター ページに追加する前に作成されたためです。 そのため、これらの既存のページを更新する必要はありません。 ただし、Web サイトに追加された新しいページには、既定で QuickLoginUI ContentPlaceHolder のコンテンツ コントロールが含まれています。 そのため、新しいコンテンツ ページを追加するたびに、これらのコンテンツ コントロールを忘れずに削除する必要があります (ログイン ページの場合と同様に、ContentPlaceHolder の既定のコンテンツをオーバーライドする場合を除きます)。

コンテンツ コントロールを削除するには、ソース ビューからその宣言型マークアップを手動で削除するか、デザイン ビューでスマート タグから [マスター コンテンツを既定として設定] リンクを選択します。 どちらの方法でも、ページからコンテンツ コントロールが削除され、同じ最終効果が得られます。

図 8 は、ブラウザーで表示した場合の Default.aspx を示しています。 Default.aspx には、宣言型マークアップで指定されているコンテンツ コントロールが 2 つだけあることを思い出してください。head 用に 1 つと MainContent 用に 1 つです。 その結果、LeftColumnContent および QuickLoginUI ContentPlaceHolder の既定のコンテンツが表示されます。

LeftColumnContent および QuickLoginUI ContentPlaceHolders の既定のコンテンツが表示されます

図 08: LeftColumnContent および QuickLoginUI ContentPlaceHolder の既定のコンテンツが表示される (クリックするとフルサイズの画像が表示されます)

まとめ

ASP.NET マスター ページ モデルでは、マスター ページ内で任意の数の ContentPlaceHolder を使用できます。 さらに、ContentPlaceHolder には既定のコンテンツが含まれています。これは、コンテンツ ページに対応するコンテンツ コントロールがない場合に生成されます。 このチュートリアルでは、マスター ページに追加の ContentPlaceHolder コントロールを含める方法と、新規と既存の両方の ASP.NET ページでこれらの新しい ContentPlaceHolder のコンテンツ コントロールを定義する方法について説明しました。 また、ContentPlaceHolder で既定のコンテンツを指定する方法についても説明しました。これは、少数のページのみが特定の領域内で標準化されたコンテンツをカスタマイズする必要があるシナリオで役立ちます。

次のチュートリアルでは、head ContentPlaceHolder について詳しく調べ、タイトル、メタ タグ、およびその他の HTML ヘッダーをページごとに宣言およびプログラムによって定義する方法について説明します。

プログラミングに満足!

作成者について

複数の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の著書は、「Sams Teach Yourself ASP.NET 3.5 in 24 Hours」です。 Mitchell 氏には、mitchell@4GuysFromRolla.com から、または http://ScottOnWriting.NET で彼のブログを介して連絡できます。

特別な感謝

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