마스터 페이지를 프로그래밍 방식으로 지정(VB)

작성자 : Scott Mitchell

PreInit 이벤트 처리기를 통해 프로그래밍 방식으로 콘텐츠 페이지의 master 페이지 설정을 확인합니다.

소개

마스터 페이지를 사용하여 Site-Wide 레이아웃 만들기의 첫 번째 예제부터 모든 콘텐츠 페이지는 지시문의 MasterPageFile 특성을 @Page 통해 선언적으로 해당 master 페이지를 참조했습니다. 예를 들어 다음 @Page 지시문은 콘텐츠 페이지를 master 페이지에 Site.master연결합니다.

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

네임스페이스의 클래스에는Page 콘텐츠 페이지의 master 페이지의 경로를 반환하는 속성이 포함되어 MasterPageFile 있습니다. 지시문에 의해 @Page 설정된 속성입니다.System.Web.UI 이 속성을 사용하여 콘텐츠 페이지의 master 페이지를 프로그래밍 방식으로 지정할 수도 있습니다. 이 방법은 페이지를 방문하는 사용자와 같은 외부 요인에 따라 master 페이지를 동적으로 할당하려는 경우에 유용합니다.

이 자습서에서는 웹 사이트에 두 번째 master 페이지를 추가하고 런타임에 사용할 master 페이지를 동적으로 결정합니다.

1단계: 페이지 수명 주기 살펴보기

콘텐츠 페이지인 ASP.NET 페이지에 대한 요청이 웹 서버에 도착할 때마다 ASP.NET 엔진은 페이지의 콘텐츠 컨트롤을 master 페이지의 해당 ContentPlaceHolder 컨트롤에 융합해야 합니다. 이 fusion은 일반적인 페이지 수명 주기를 진행할 수 있는 단일 컨트롤 계층 구조를 만듭니다.

그림 1에서는 이러한 융합을 보여 줍니다. 그림 1의 1단계는 초기 콘텐츠 및 master 페이지 컨트롤 계층 구조를 보여줍니다. PreInit 단계의 끝에 있는 페이지의 콘텐츠 컨트롤이 master 페이지의 해당 ContentPlaceHolders에 추가됩니다(2단계). 이 융합 후에는 master 페이지가 융합된 컨트롤 계층 구조의 루트 역할을 합니다. 그런 다음 이 융합된 컨트롤 계층 구조가 페이지에 추가되어 완료된 컨트롤 계층 구조(3단계)를 생성합니다. 결과적으로 페이지의 컨트롤 계층에는 융합된 컨트롤 계층 구조가 포함됩니다.

마스터 페이지 및 콘텐츠 페이지의 컨트롤 계층 구조는 PreInit 단계 중에 함께 융합됩니다.

그림 01: 마스터 페이지 및 콘텐츠 페이지의 컨트롤 계층 구조는 PreInit 단계 중에 함께 융합됩니다(전체 크기 이미지를 보려면 클릭).

2단계: 코드에서 속성 설정MasterPageFile

이 fusion에서 master 페이지는 개체 MasterPageFile 의 속성 값에 Page 따라 달라집니다. MasterPageFile 지시문에서 @Page 특성을 설정하면 페이지 수명 주기의 MasterPageFile 첫 번째 단계인 초기화 단계에서 의 속성을 할당Page하는 순 효과가 있습니다. 또는 프로그래밍 방식으로 이 속성을 설정할 수 있습니다. 그러나 그림 1의 융합이 발생하기 전에 이 속성을 설정해야 합니다.

PreInit 단계가 시작될 때 개체는 Page 이벤트를 발생시키고 메서드 PreInit 를 호출합니다OnPreInit. master 페이지를 프로그래밍 방식으로 설정하려면 이벤트에 대한 이벤트 처리기를 만들거나 메서드를 재정의 PreInitOnPreInit 수 있습니다. 두 접근 방식을 모두 살펴보겠습니다.

먼저 사이트의 홈페이지에 대한 코드 숨김 클래스 파일인 을 엽니다 Default.aspx.vb. 다음 코드를 입력하여 페이지 PreInit 이벤트에 대한 이벤트 처리기를 추가합니다.

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

여기에서 속성을 설정할 MasterPageFile 수 있습니다. "~/Site" 값을 할당할 수 있도록 코드를 업데이트합니다. 속성에 MasterPageFile "를 master.

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

중단점을 설정하고 디버깅을 시작하면 페이지를 방문할 때마다 Default.aspx 또는 이 페이지에 Page_PreInit 대한 포스트백이 있을 때마다 이벤트 처리기가 실행되고 MasterPageFile 속성이 "~/Site.master"에 할당되는 것을 볼 수 있습니다.

또는 클래스의 메서드를 Page 재정의 OnPreInit 하고 속성을 설정할 MasterPageFile 수 있습니다. 이 예제에서는 특정 페이지에서 master 페이지를 설정하지 않고 에서 BasePage설정해 보겠습니다. 마스터 페이지의 제목, 메타 태그 및 기타 HTML 헤더 지정 자습서에서 사용자 지정 기본 페이지 클래스(BasePage)를 다시 만들었습니다. 현재 BasePage 는 사이트 맵 데이터를 기반으로 페이지의 속성을 설정하는 클래스 OnLoadComplete 의 메서드를 재정 PageTitle 합니다. 프로그래밍 방식으로 master 페이지를 지정하도록 메서드를 재정 OnPreInit 의하도록 업데이트 BasePage 해 보겠습니다.

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

모든 콘텐츠 페이지는 에서 BasePage파생되므로 이제 모든 콘텐츠 페이지에 프로그래밍 방식으로 master 페이지가 할당됩니다. 이 시점에서 의 PreInit 이벤트 처리기는 Default.aspx.vb 불필요합니다. 자유롭게 제거할 수 있습니다.

지시문은@Page어떻습니까?

약간 혼란스러울 수 있는 것은 콘텐츠 페이지의 속성이 이제 클래스의 메서드와 각 콘텐츠 페이지의 MasterPageFile@Page 지시문에 OnPreInit 있는 BasePage 특성을 통해 MasterPageFile 프로그래밍 방식으로 두 위치에 지정되고 있다는 것입니다.

페이지 수명 주기의 첫 번째 단계는 초기화 단계입니다. 이 단계에서 Page 개체의 MasterPageFile 속성은 지시문에 MasterPageFile@Page 있는 특성 값(제공된 경우)에 할당됩니다. PreInit 단계는 초기화 단계를 따르며 여기서는 프로그래밍 방식으로 개체의 MasterPageFile 속성을 설정 Page 하여 지시문에서 @Page 할당된 값을 덮어씁니다. 개체의 MasterPageFile 속성을 프로그래밍 방식으로 설정 Page 하기 때문에 최종 사용자의 환경에 영향을 주지 않고 지시문에서 @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 class=@Page 지시문의 MasterPageFile 특성을 사용하여 디자인 뷰 렌더링" />

그림 02: Visual Studio에서 @Page 지시문의 MasterPageFile 특성을 사용하여 디자인 뷰 렌더링(전체 크기 이미지를 보려면 클릭)

3단계: 대체 마스터 페이지 만들기

콘텐츠 페이지의 master 페이지는 런타임에 프로그래밍 방식으로 설정할 수 있으므로 일부 외부 조건에 따라 특정 master 페이지를 동적으로 로드할 수 있습니다. 이 기능은 사이트의 레이아웃이 사용자에 따라 달라야 하는 상황에서 유용할 수 있습니다. instance 경우 블로그 엔진 웹 애플리케이션을 사용하면 사용자가 각 레이아웃이 다른 master 페이지와 연결된 블로그의 레이아웃을 선택할 수 있습니다. 런타임에 방문자가 사용자의 블로그를 볼 때 웹 애플리케이션은 블로그의 레이아웃을 확인하고 해당 master 페이지를 콘텐츠 페이지와 동적으로 연결해야 합니다.

일부 외부 조건에 따라 런타임에 master 페이지를 동적으로 로드하는 방법을 살펴보겠습니다. 현재 웹 사이트에는 하나의 master 페이지(Site.master)만 포함되어 있습니다. 런타임에 master 페이지를 선택하는 방법을 보여 주는 또 다른 master 페이지가 필요합니다. 이 단계에서는 새 master 페이지를 만들고 구성하는 데 중점을 둡니다. 4단계에서는 런타임에 사용할 master 페이지를 결정하는 방법을 살펴봅니다.

라는 Alternate.master루트 폴더에 새 master 페이지를 만듭니다. 또한 라는 AlternateStyles.css웹 사이트에 새 스타일시트를 추가합니다.

웹 사이트에 다른 마스터 페이지 및 CSS 파일 추가

그림 03: 웹 사이트에 다른 마스터 페이지 및 CSS 파일 추가(전체 크기 이미지를 보려면 클릭)

페이지 맨 위에 제목을 Alternate.master 표시하도록 master 페이지를 디자인했습니다. 왼쪽 열을 분배하고 해당 콘텐츠를 ContentPlaceHolder 컨트롤 아래로 MainContent 이동했습니다. 이 컨트롤은 이제 페이지의 전체 너비에 걸쳐 있습니다. 또한 순서가 지정되지 않은 단원 목록을 닉스하고 위의 MainContent가로 목록으로 바꿉니다. 또한 master 페이지에서 사용하는 글꼴과 색을 업데이트했습니다(확장에 따라 콘텐츠 페이지). 그림 4는 master 페이지를 사용하는 경우를 Alternate.master 보여줍니다Default.aspx.

참고

ASP.NET 테마를 정의하는 기능이 포함되어 있습니다. 테마는 런타임에 페이지에 적용할 수 있는 이미지, CSS 파일 및 스타일 관련 웹 컨트롤 속성 설정의 컬렉션입니다. 테마는 사이트의 레이아웃이 표시되는 이미지와 CSS 규칙에 따라 다른 경우 이동하는 방법입니다. 다른 웹 컨트롤을 사용하거나 레이아웃이 근본적으로 다른 경우와 같이 레이아웃이 더 크게 다른 경우 별도의 master 페이지를 사용해야 합니다. 테마에 대한 자세한 내용은 이 자습서의 끝에 있는 추가 읽기 섹션을 참조하세요.

이제 콘텐츠 페이지에서 새로운 모양과 느낌을 사용할 수 있습니다.

그림 04: 이제 콘텐츠 페이지에서 새 모양과 느낌을 사용할 수 있습니다(전체 크기 이미지를 보려면 클릭).

master 및 콘텐츠 페이지의 태그가 융합 MasterPage 되면 클래스는 콘텐츠 페이지의 모든 콘텐츠 컨트롤이 master 페이지의 ContentPlaceHolder를 참조하는지 확인합니다. 존재하지 않는 ContentPlaceHolder를 참조하는 콘텐츠 컨트롤이 발견되면 예외가 throw됩니다. 즉, 콘텐츠 페이지에 할당되는 master 페이지에 콘텐츠 페이지의 각 콘텐츠 컨트롤에 대한 ContentPlaceHolder가 있어야 합니다.

master 페이지에는 Site.master 4개의 ContentPlaceHolder 컨트롤이 포함되어 있습니다.

  • head
  • MainContent
  • QuickLoginUI
  • LeftColumnContent

웹 사이트의 일부 콘텐츠 페이지에는 하나 또는 두 개의 콘텐츠 컨트롤만 포함됩니다. 사용 가능한 각 ContentPlaceHolders에 대한 콘텐츠 컨트롤이 포함됩니다. 의 모든 ContentPlaceHolders Site.master 에 대한 콘텐츠 컨트롤이 있는 콘텐츠 페이지에 새 master 페이지(Alternate.master)를 할당할 수 있는 경우 와 동일한 ContentPlaceHolder 컨트롤Site.master도 포함하는 것이 필수적입니다Alternate.master.

Alternate.master master 페이지를 내 페이지와 비슷하게 표시하려면(그림 4 참조) 스타일시트에서 AlternateStyles.css master 페이지의 스타일을 정의하여 시작합니다. 에 다음 규칙을 추가합니다 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 프레임워크를 사용하는 웹 사이트의 해당 페이지에 필요한 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>

새 마스터 페이지 테스트

이 새 master 페이지를 테스트하려면 속성에 BasePage"~/Alternate.maser" 이 할당되도록 클래스의 OnPreInit 메서드를 MasterPageFile 업데이트한 다음 웹 사이트를 방문합니다. 및 ~/Admin/Products.aspx~/Admin/AddProduct.aspx 제외하고 모든 페이지는 오류 없이 작동해야 합니다. 에서 DetailsView에 ~/Admin/AddProduct.aspx 제품을 추가하면 NullReferenceException master 페이지의 속성을 설정하려는 코드 줄의 GridMessageText 가 생성됩니다. 를 방문 ~/Admin/Products.aspxInvalidCastException 하면 "'ASP.alternate_master' 형식의 개체를 'ASP.site_master' 형식으로 캐스팅할 수 없습니다."라는 메시지와 함께 페이지 로드가 throw됩니다.

이러한 오류는 코드 숨김 클래스에 Site.master 에 정의 Alternate.master되지 않은 공용 이벤트, 속성 및 메서드가 포함되어 있기 때문에 발생합니다. 이 두 페이지의 @MasterType 태그 부분에는 master 페이지를 참조하는 지시문이 Site.master 있습니다.

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

또한 의 DetailsView 이벤트 처리기에 ~/Admin/AddProduct.aspx 는 느슨한 형식 Page.MasterItemInserted 속성을 형식의 개체로 캐스팅하는 코드가 포함되어 있습니다Site. @MasterType 지시문(이러한 방식으로 사용됨)과 이벤트 처리기의 캐스트 ItemInserted 는 및 페이지를 master 페이지와 ~/Admin/Products.aspxSite.master 긴밀하게 결합합니다~/Admin/AddProduct.aspx.

이 긴밀한 결합을 끊기 위해 공용 멤버에 대한 정의를 포함하는 공통 기본 클래스를 사용하고 Site.masterAlternate.master 파생할 수 있습니다. 그런 다음 이 일반적인 기본 형식을 @MasterType 참조하도록 지시문을 업데이트할 수 있습니다.

사용자 지정 기본 마스터 페이지 클래스 만들기

라는 BaseMasterPage.vb 폴더에 App_Code 새 클래스 파일을 추가하고 에서 System.Web.UI.MasterPage파생되도록 합니다. 메서드와 GridMessageText 속성을 에 BaseMasterPage정의 RefreshRecentProductsGrid 해야 하지만 이러한 멤버는 master 페이지(RecentProductsGridView 및 레이블)와 관련된 웹 컨트롤에서 GridMessage 작동하기 Site.master 때문에 단순히 이 위치에서 이동할 Site.master 수는 없습니다.

이러한 멤버가 정의되지만 실제로 의 파생 클래스(Site.masterAlternate.master)에 의해 BaseMasterPage구현되는 방식으로 구성 BaseMasterPage 해야 합니다. 이 유형의 상속은 클래스를 로 표시하고 해당 멤버를 로 MustInheritMustOverride표시하여 가능합니다. 즉, 클래스와 해당 두 멤버에 이러한 키워드를 추가하면 및 GridMessageTextBaseMasterPage 구현 RefreshRecentProductsGrid 되지 않았지만 파생 클래스가 있음을 알려 줍니다.

또한 에서 이벤트를 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 의 메서드를 호출하여 Button의 Click 이벤트 처리기에서 DoublePrice 이벤트를 발생 PricesDoubled 시키는 코드를 업데이트합니다.

이러한 수정 후 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

또한 두 MustOverride 멤버에서 BaseMasterPage 파생되고 재정의되도록 의 코드 숨김 클래스를 업데이트Alternate.master해야 합니다. Alternate.master 그러나 최신 제품을 나열하는 GridView 또는 새 제품이 데이터베이스에 추가된 후 메시지를 표시하는 레이블이 포함되어 있지 않으므로 이러한 메서드는 아무 작업도 수행할 필요가 없습니다.

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 완료하고 두 개의 master 페이지가 확장되었으므로 마지막 단계는 및 ~/Admin/Products.aspx 페이지를 업데이트 ~/Admin/AddProduct.aspx 하여 이 일반적인 형식을 참조하는 것입니다. 두 페이지의 지시문을 다음에서 변경 @MasterType 하여 시작합니다.

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

대상:

<%@ MasterType TypeName="BaseMasterPage" %>

이제 속성은 @MasterType 파일 경로를 참조하는 대신 기본 형식(BaseMasterPage)을 참조합니다. 따라서 두 페이지의 코드 숨김 클래스에 사용되는 강력한 형식 Master 의 속성은 이제 형식이 아닌 형식 BaseMasterPageSite입니다. 이 변경 내용이 있는 경우 를 다시 방문합니다 ~/Admin/Products.aspx. 이전에는 페이지가 master 페이지를 사용하도록 Alternate.master 구성되었지만 @MasterType 지시문이 파일을 참조 Site.master 했기 때문에 캐스팅 오류가 발생했습니다. 그러나 이제 페이지는 오류 없이 렌더링됩니다. 이는 master 페이지가 확장되므로 형식 BaseMasterPage 의 개체로 캐스팅할 수 있기 Alternate.master 때문입니다.

에서 수행해야 하는 작은 변경 내용이 하나 있습니다 ~/Admin/AddProduct.aspx. 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 단계에서 모든 콘텐츠 페이지의 속성을 하드 코딩된 값으로 설정합니다. 이 코드를 업데이트하여 일부 외부 요소의 master 페이지를 기반으로 할 수 있습니다. 로드할 master 페이지는 현재 로그온한 사용자의 기본 설정에 따라 달라집니다. 이 경우 현재 방문하는 사용자의 master 페이지 기본 설정을 조회하는 의 메서드에 BasePage 코드를 OnPreInit 작성해야 합니다.

사용자가 사용할 Site.master master 페이지를 선택하거나 Alternate.master 세션 변수에 저장할 수 있는 웹 페이지를 만들어 보겠습니다. 먼저 라는 ChooseMasterPage.aspx루트 디렉터리에 새 웹 페이지를 만듭니다. 이 페이지(또는 그 이후의 다른 콘텐츠 페이지)를 만들 때 master 페이지가 에서 프로그래밍 방식으로 BasePage설정되므로 master 페이지에 바인딩할 필요가 없습니다. 그러나 새 페이지를 master 페이지에 바인딩하지 않으면 새 페이지의 기본 선언적 태그에는 웹 양식 및 master 페이지에서 제공하는 기타 콘텐츠가 포함됩니다. 이 태그를 적절한 콘텐츠 컨트롤로 수동으로 바꿔야 합니다. 따라서 새 ASP.NET 페이지를 master 페이지에 바인딩하는 것이 더 쉽습니다.

참고

Alternate.master 에는 동일한 ContentPlaceHolder 컨트롤 집합이 있으므로 Site.master 새 콘텐츠 페이지를 만들 때 선택하는 master 페이지는 중요하지 않습니다. 일관성을 위해 를 사용하는 Site.master것이 좋습니다.

웹 사이트에 새 콘텐츠 페이지 추가

그림 05: 웹 사이트에 새 콘텐츠 페이지 추가(전체 크기 이미지를 보려면 클릭)

이 단원의 Web.sitemap 항목을 포함하도록 파일을 업데이트합니다. 마스터 페이지 및 ASP.NET AJAX 단원의 아래에 <siteMapNode> 다음 태그를 추가합니다.

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

페이지에 콘텐츠를 추가하기 ChooseMasterPage.aspx 전에 잠시 페이지의 코드 숨김 클래스를 업데이트하여 에서 파생 BasePage 되도록 합니다(가 아닌 System.Web.UI.Page). 그런 다음 페이지에 DropDownList 컨트롤을 추가하고, 해당 ID 속성을 MasterPageChoice로 설정하고, 값이 "~/Site.master" 및 "~/Alternate.master"인 두 개의 ListItems Text 를 추가합니다.

단추 웹 컨트롤을 페이지에 추가하고 해당 ID 및 속성을 SaveLayout 각각 및 Text "레이아웃 선택 저장"으로 설정합니다. 이 시점에서 페이지의 선언적 태그는 다음과 유사하게 표시됩니다.

<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>

페이지를 처음 방문하면 사용자가 현재 선택한 master 페이지 선택을 표시해야 합니다. 이벤트 처리기를 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

위의 코드는 첫 번째 페이지 방문에서만 실행되며 후속 포스트백에서는 실행되지 않습니다. 먼저 세션 변수 MyMasterPage 가 있는지 확인합니다. 이 경우 DropDownList에서 일치하는 ListItem을 MasterPageChoice 찾으려고 시도합니다. 일치하는 ListItem이 발견되면 해당 Selected 속성은 로 True설정됩니다.

또한 사용자의 선택을 Session 변수에 저장하는 코드도 MyMasterPage 필요합니다. Button의 Click 이벤트에 대한 SaveLayout 이벤트 처리기를 만들고 다음 코드를 추가합니다.

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 master 페이지가 이미 선택되어 있습니다. 따라서 사용자의 드롭다운 목록 선택은 다음 페이지를 방문할 때까지 적용되지 않습니다. 는 Response.Redirect 브라우저에서 를 강제로 다시 요청 ChooseMasterPage.aspx합니다.

페이지가 ChooseMasterPage.aspx 완료되면 최종 작업은 BasePage Session 변수의 값에 따라 속성을 할당 MasterPageFile 하는 MyMasterPage 것입니다. 세션 변수가 설정되지 않은 경우 기본값은 BasePage 입니다 Site.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 속성을 이벤트 처리기에서 OnPreInit 두 개의 별도 메서드로 할당 Page 하는 코드를 이동했습니다. 이 첫 번째 메서드인 SetMasterPageFile는 두 번째 메서드 GetMasterPageFileFromSession에서 MasterPageFile 반환된 값에 속성을 할당합니다. 필요한 경우 확장 BasePage 되는 이후 클래스가 필요에 따라 사용자 지정 논리를 구현하도록 재정의할 수 있도록 메서드 Overridable 를 표시 SetMasterPageFile 했습니다. 다음 자습서에서는 의 속성을 재정의 SetMasterPageFile 하는 BasePage예제를 살펴보겠습니다.

이 코드가 있는 상태에서 페이지를 방문합니다 ChooseMasterPage.aspx . 처음에는 Site.master master 페이지가 선택되었지만(그림 6 참조) 사용자는 드롭다운 목록에서 다른 master 페이지를 선택할 수 있습니다.

사이트를 사용하여 콘텐츠 페이지가 표시됩니다. master 마스터 페이지

그림 06: 마스터 페이지를 사용하여 Site.master 콘텐츠 페이지 표시(전체 크기 이미지를 보려면 클릭)

이제 대체를 사용하여 콘텐츠 페이지가 표시됩니다. master 마스터 페이지

그림 07: 이제 마스터 페이지를 사용하여 Alternate.master 콘텐츠 페이지가 표시됩니다(전체 크기 이미지를 보려면 클릭).

요약

콘텐츠 페이지를 방문하면 콘텐츠 컨트롤이 master 페이지의 ContentPlaceHolder 컨트롤과 융합됩니다. 콘텐츠 페이지의 master 페이지는 초기화 단계에서 지시문의 특성에 @Page 할당된 클래스의 MasterPageFile 속성으로 표시됩니다Page.MasterPageFile 이 자습서에서 알 수 있듯이 PreInit 단계가 MasterPageFile 끝나기 전에 속성에 값을 할당할 수 있습니다. 프로그래밍 방식으로 master 페이지를 지정할 수 있으면 외부 요인에 따라 콘텐츠 페이지를 master 페이지에 동적으로 바인딩하는 것과 같은 고급 시나리오의 문이 열립니다.

행복한 프로그래밍!

추가 정보

이 자습서에서 설명하는 topics 대한 자세한 내용은 다음 리소스를 참조하세요.

저자 정보

여러 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술을 연구해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 샘스 티치 유어셀프 ASP.NET 3.5 24 시간. Scott은 에서 mitchell@4GuysFromRolla.com 또는 에서 자신의 블로그 http://ScottOnWriting.NET를 통해 연락할 수 있습니다.

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 Suchi Banerjee였습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 에서 줄을 놓습니다. mitchell@4GuysFromRolla.com