다음을 통해 공유


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

스콧 미첼

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

소개

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

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

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

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

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

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

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

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

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

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

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

PreInit 단계가 시작될 때 개체는 Page 이벤트를 발생시키고 메서드 PreInit 를 호출합니다OnPreInit. 마스터 페이지를 프로그래밍 방식으로 설정하려면 이벤트에 대한 이벤트 처리기를 만들거나 메서드를 재정의 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.master" 값을 속성에 할당하도록 코드를 업데이트합니다 MasterPageFile .

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

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

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

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

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

페이지 수명 주기의 첫 번째 단계는 초기화 단계입니다. 이 단계에서 Page 개체의 MasterPageFile 속성에는 지시문에 @Page 있는 특성 값MasterPageFile(제공된 경우)이 할당됩니다. PreInit 단계는 초기화 단계를 따르며 여기서는 개체의 MasterPageFile 속성을 프로그래밍 방식으로 설정 Page 하여 지시문에서 @Page 할당된 값을 덮어씁니다. 개체의 MasterPageFile 속성을 프로그래밍 방식으로 설정 Page 하므로 최종 사용자의 환경에 영향을 주지 않고 지시문에서 @Page 특성을 제거할 MasterPageFile 수 있습니다. 이를 설득하려면 계속 진행하여 지시문 Default.aspx 에서 @Page 특성을 제거 MasterPageFile 한 다음 브라우저를 통해 페이지를 방문합니다. 예상한 대로 출력은 특성이 제거되기 전과 동일합니다.

속성이 MasterPageFile 지시문을 통해 @Page 설정되었는지 또는 프로그래밍 방식으로 설정되었는지 여부는 최종 사용자의 환경에 중요하지 않습니다. 그러나 지시문의 MasterPageFile @Page 특성은 디자인 타임 동안 Visual Studio에서 디자이너에서 WYSIWYG 뷰를 생성하는 데 사용됩니다. Visual Studio로 돌아가 Default.aspx 디자이너로 이동하면 "마스터 페이지 오류: 페이지에 마스터 페이지 참조가 필요한 컨트롤이 있지만 지정되지 않은 컨트롤"(그림 2 참조)이 표시됩니다.

즉, Visual Studio에서 @Page 풍부한 디자인 타임 환경을 사용하려면 지시문에 특성을 남겨 MasterPageFile 두어야 합니다.

Visual Studio에서 <span 클래스= 사용@Page 지시문의 MasterPageFile 특성을 사용하여 디자인 뷰 렌더링" />

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

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

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

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

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

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

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

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

참고 항목

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

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

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

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

마스터 페이지에는 Site.master 다음 네 가지 ContentPlaceHolder 컨트롤이 포함됩니다.

  • head
  • MainContent
  • QuickLoginUI
  • LeftColumnContent

웹 사이트의 일부 콘텐츠 페이지에는 하나 또는 두 개의 콘텐츠 컨트롤만 포함됩니다. 다른 항목에는 사용 가능한 각 ContentPlaceHolders에 대한 콘텐츠 컨트롤이 포함됩니다. 모든 ContentPlaceHolders에 대한 콘텐츠 컨트롤이 있는 콘텐츠 페이지에 새 마스터 페이지(Alternate.master)를 할당할 수 있는 Site.master 경우 동일한 ContentPlaceHolder 컨트롤도 포함해야 Alternate.master 합니다 Site.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 프레임워크를 사용하는 웹 사이트의 해당 페이지에 필요한 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.maser" 이 할당되도록 클래스의 OnPreInit 메서드를 MasterPageFile 업데이트한 다음 웹 사이트를 방문합니다. 다음 두 ~/Admin/AddProduct.aspx ~/Admin/Products.aspx가지를 제외하고 모든 페이지는 오류 없이 작동해야 합니다. DetailsView에 ~/Admin/AddProduct.aspx 제품을 추가하면 마스터 페이지의 속성을 설정하려고 시도하는 코드 줄에서 GridMessageText 결과가 NullReferenceException 생성됩니다. 방문 ~/Admin/Products.aspx InvalidCastException 하면 "'ASP.alternate_master' 형식의 개체를 'ASP.site_master' 형식으로 캐스팅할 수 없습니다."라는 메시지와 함께 페이지 로드가 throw됩니다.

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

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

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

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

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

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

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

또한 이벤트를 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

다음으로 코드 숨김 클래스BaseMasterPageSite.master 이동하여 파생되도록 합니다. 표시된 MustOverride 멤버가 포함되어 있으므로 BaseMasterPage 여기에서 Site.master해당 멤버를 재정의해야 합니다. Overrides 메서드 및 속성 정의에 키워드를 추가합니다. 또한 기본 클래스 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 완료하고 두 개의 마스터 페이지가 확장되었으므로 마지막 단계는 이 공통 형식을 참조하도록 페이지 및 ~/Admin/Products.aspx 페이지를 업데이트 ~/Admin/AddProduct.aspx 하는 것입니다. 두 페이지의 지시문을 다음에서 변경 @MasterType 하여 시작합니다.

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

다음으로 변경:

<%@ MasterType TypeName="BaseMasterPage" %>

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

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

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

참고 항목

Alternate.master ContentPlaceHolder 컨트롤 집합이 동일하기 때문에 Site.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" 값으로 Text 두 개의 ListItems를 추가합니다.

단추 웹 컨트롤을 페이지에 추가하고 해당 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 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설정됩니다.

또한 사용자의 선택을 세션 변수에 저장하는 코드도 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 마스터 페이지가 이미 선택되었습니다. 따라서 사용자의 드롭다운 목록 선택은 다음 페이지를 방문할 때까지 적용되지 않습니다. Response.Redirect 브라우저가 다시 요청ChooseMasterPage.aspx하도록 합니다.

페이지가 ChooseMasterPage.aspx 완료되면 최종 작업은 BasePage 세션 변수의 값에 따라 속성을 할당 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 마스터 페이지가 선택되었지만(그림 6 참조) 사용자는 드롭다운 목록에서 다른 마스터 페이지를 선택할 수 있습니다.

Site.master 마스터 페이지를 사용하여 콘텐츠 페이지 표시

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

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

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

요약

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

행복한 프로그래밍!

추가 정보

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

작성자 정보

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