Программное указание эталонной страницы (C#)
Проверяет настройку главной страницы страницы содержимого программным способом с помощью обработчика событий PreInit.
Введение
Так как первый пример создания макета на уровне сайта с помощью главных страниц все страницы содержимого ссылаются на главную страницу декларативно с помощью атрибута MasterPageFile
в директиве@Page
. Например, следующая @Page
директива связывает страницу содержимого с главной страницей Site.master
:
<%@ Page Language="C#" MasterPageFile="~/Site.master" ... %>
Класс Page
в System.Web.UI
пространстве имен включает MasterPageFile
свойство, возвращающее путь к главной странице страницы контента. Это свойство, заданное директивой@Page
. Это свойство также можно использовать для программного указания главной страницы страницы содержимого. Этот подход полезен, если вы хотите динамически назначить главную страницу на основе внешних факторов, таких как пользователь, посещающий страницу.
В этом руководстве мы добавим на наш веб-сайт вторую главную страницу и динамически определим, какую главную страницу следует использовать во время выполнения.
Шаг 1. Просмотр жизненного цикла страницы
Каждый раз, когда запрос поступает на веб-сервер для страницы ASP.NET, которая является страницей содержимого, подсистема ASP.NET должна использовать элементы управления "Содержимое" страницы в соответствующие элементы управления ContentPlaceHolder главной страницы. Это слияние создает единую иерархию элементов управления, которая затем может проходить через типичный жизненный цикл страницы.
Рис. 1 иллюстрирует это слияние. На шаге 1 на рис. 1 показаны начальные иерархии содержимого и элементов управления главной страницей. В конце конечной части этапа PreInit элементы управления "Содержимое" на странице добавляются на соответствующую страницу ContentPlaceHolders на главной странице (шаг 2). После этого слияния эталонная страница служит корнем иерархии сплавленного элемента управления. Затем эта сплавленная иерархия элементов управления добавляется на страницу для создания завершенной иерархии элементов управления (шаг 3). Чистый результат заключается в том, что иерархия элементов управления страницы включает в себя плавленную иерархию элементов управления.
Рис. 01. Иерархии элементов управления главной страницы и страницы содержимого объединяются во время этапа предварительной подготовки (щелкните, чтобы просмотреть изображение полного размера)
Шаг 2. ЗаданиеMasterPageFile
свойства из кода
Какие главные страницы участвуют в этом слиянии, зависят от значения Page
свойства объекта MasterPageFile
. MasterPageFile
Задание атрибута в @Page
директиве имеет чистый эффект назначения Page
MasterPageFile
свойства во время этапа инициализации, который является самым первым этапом жизненного цикла страницы. Кроме того, можно программно задать это свойство. Однако необходимо задать это свойство перед слиянием на рис. 1.
В начале этапа Page
PreInit объект вызывает его PreInit
событие и вызывает его OnPreInit
метод. Чтобы задать эталонную страницу программным способом, можно создать обработчик событий для PreInit
события или переопределить OnPreInit
метод. Давайте рассмотрим оба метода.
Начните с открытия Default.aspx.cs
файла класса code-behind для домашней страницы нашего сайта. Добавьте обработчик событий для события страницы PreInit
, введя следующий код:
protected void Page_PreInit(object sender, EventArgs e)
{
}
Здесь можно задать MasterPageFile
свойство. Обновите код, чтобы он назначит свойству значение ~/Site.master MasterPageFile
.
protected void Page_PreInit(object sender, EventArgs e)
{
this.MasterPageFile = "~/Site.master";
}
Если установить точку останова и начать с отладки, вы увидите, что при Default.aspx
каждом посещении страницы или при наличии обратной передачи на эту страницу обработчик событий выполняется, Page_PreInit
а MasterPageFile
свойство назначается "~/Site.master".
Кроме того, можно переопределить Page
метод класса OnPreInit
и задать MasterPageFile
его. В этом примере давайте не задали главную страницу на определенной странице, а не из BasePage
. Помните, что мы создали пользовательский базовый класс страницы (BasePage
) обратно в руководстве по указанию заголовка, мета тегов и других заголовков HTML в руководстве по главной странице . BasePage
В настоящее время переопределяет Page
метод классаOnLoadComplete
, где он задает свойство страницы Title
на основе данных карты сайта. Давайте обновим BasePage
метод, чтобы также переопределить OnPreInit
метод, чтобы программно указать главную страницу.
protected override void OnPreInit(EventArgs e)
{
this.MasterPageFile = "~/Site.master";
base.OnPreInit(e);
}
Так как все страницы содержимого являются производными от BasePage
них, все из них теперь назначаемой главной странице программным способом. На этом этапе PreInit
обработчик событий не Default.aspx.cs
является лишним. Вы можете удалить его.
Что такое директива@Page
?
Что может быть немного запутано, заключается в том, что свойства страниц контента MasterPageFile
теперь указываются в двух местах: программно в BasePage
методе класса OnPreInit
, а также через MasterPageFile
атрибут в директиве каждой страницы @Page
содержимого.
Первым этапом жизненного цикла страницы является этап инициализации. На этом этапе Page
свойству объекта MasterPageFile
присваивается значение MasterPageFile
атрибута в @Page
директиве (если оно указано). Этап PreInit следует этапу инициализации, и здесь мы программно задали Page
свойство объекта MasterPageFile
, тем самым перезаписав значение, назначенное директивой @Page
. Так как мы устанавливаем Page
свойство объекта MasterPageFile
программным способом, мы можем удалить MasterPageFile
атрибут из @Page
директивы, не влияя на взаимодействие с конечным пользователем. Чтобы убедить себя в этом, перейдите к этому и удалите MasterPageFile
атрибут из @Page
директивы Default.aspx
, а затем посетите страницу через браузер. Как ожидается, выходные данные совпадают с тем, что и до удаления атрибута.
MasterPageFile
Указывает, задано ли свойство с помощью @Page
директивы или программно не соответствует интерфейсу конечного пользователя. MasterPageFile
Однако атрибут в @Page
директиве используется Visual Studio во время разработки для создания представления WYSIWYG в конструкторе. Если вы вернетесь в Visual Studio и перейдите к Default.aspx
конструктору, появится сообщение "Ошибка главной страницы: страница содержит элементы управления, требующие ссылки на эталонную страницу, но не указано" (см. рис. 2).
Короче говоря, необходимо оставить MasterPageFile
атрибут в @Page
директиве, чтобы насладиться богатым опытом разработки в Visual Studio.
Атрибут masterPageFile директивы @Page для отображения представления конструктора" />
Рис. 02. Visual Studio использует @Page
атрибут директивы MasterPageFile
для отображения представления конструктора (щелкните, чтобы просмотреть изображение полного размера)
Шаг 3. Создание альтернативной главной страницы
Так как эталонная страница страницы содержимого может быть настроена программным способом во время выполнения, можно динамически загружать определенную главную страницу на основе некоторых внешних критериев. Эта функция может оказаться полезной в ситуациях, когда макет сайта должен отличаться в зависимости от пользователя. Например, веб-приложение подсистемы блога может позволить пользователям выбрать макет для своего блога, где каждый макет связан с другой главной страницей. Во время выполнения, когда посетитель просматривает блог пользователя, веб-приложение потребуется определить макет блога и динамически связать соответствующую главную страницу со страницей содержимого.
Давайте рассмотрим, как динамически загружать главную страницу во время выполнения на основе некоторых внешних критериев. Наш веб-сайт в настоящее время содержит только одну главную страницу (Site.master
). Нам нужна другая эталонная страница, чтобы иллюстрировать выбор главной страницы во время выполнения. Этот шаг посвящен созданию и настройке новой главной страницы. Шаг 4 определяет, какую главную страницу следует использовать во время выполнения.
Создайте главную страницу в корневой папке с именем Alternate.master
. Кроме того, добавьте новую таблицу стилей на веб-сайт с именем AlternateStyles.css
.
Рис. 03. Добавление другой главной страницы и CSS-файла на веб-сайт (щелкните, чтобы просмотреть изображение полного размера)
Я разработал Alternate.master
эталонную страницу, чтобы название отображалось в верхней части страницы, в центре и на фоне военно-морского флота. Я отпустил левый столбец и переместил содержимое под элементом MainContent
управления ContentPlaceHolder, который теперь охватывает всю ширину страницы. Кроме того, я никсировал список неупорядоченных уроков и заменил его горизонтальным списком выше MainContent
. Я также обновил шрифты и цвета, используемые главной страницей (и, по расширению, ее страницы содержимого). На рисунке 4 показано Default.aspx
при использовании главной Alternate.master
страницы.
Примечание.
ASP.NET включает возможность определения тем. Тема — это коллекция изображений, CSS-файлов и параметров свойств веб-элемента управления стилем, которые можно применить к странице во время выполнения. Темы — это способ идти, если макеты сайта отличаются только в изображениях, отображаемых и по их правилам CSS. Если макеты отличаются значительно, например использование различных веб-элементов управления или радикально другой макет, вам потребуется использовать отдельные главные страницы. Дополнительные сведения о темах см. в разделе "Дополнительное чтение" в конце этого руководства.
Рис. 04. Теперь страницы содержимого могут использовать новый внешний вид и ощущение (щелкните, чтобы просмотреть изображение полного размера)
При слиянии MasterPage
разметки главных и контентных страниц класс проверяет, что каждый элемент управления содержимым на странице содержимого ссылается на ContentPlaceHolder на главной странице. Исключение возникает, если элемент управления "Содержимое", ссылающийся на несуществующий ContentPlaceHolder, найден. Другими словами, необходимо, чтобы главная страница, назначаемая странице содержимого, имеет ContentPlaceHolder для каждого элемента управления контентом на странице содержимого.
Главная Site.master
страница включает четыре элемента управления ContentPlaceHolder:
head
MainContent
QuickLoginUI
LeftColumnContent
Некоторые страницы содержимого на нашем веб-сайте включают только один или два элемента управления содержимым; другие включают элемент управления "Контент" для каждого из доступных ContentPlaceHolders. Если новая эталонная страница (Alternate.master
) когда-либо может быть назначена этим страницам контента, имеющим элементы управления содержимым для всех ContentPlaceHolders, 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
. Как видно, содержит четыре элемента управления ContentPlaceHolder с теми же значениями, Alternate.master
что и элементы управления ContentPlaceHolder в Site.master
.ID
Кроме того, он включает элемент управления ScriptManager, который необходим для этих страниц на нашем веб-сайте, который использует платформу ASP.NET AJAX.
<!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
метод класса OnPreInit
, чтобы MasterPageFile
свойство было назначено значение ~/Alternate.master, а затем посетите веб-сайт. Каждая страница должна функционировать без ошибок, за исключением двух: ~/Admin/AddProduct.aspx
и ~/Admin/Products.aspx
. Добавление продукта в DetailsView ~/Admin/AddProduct.aspx
приводит к получению NullReferenceException
строки кода, которая пытается задать свойство главной страницы GridMessageText
. При посещении ~/Admin/Products.aspx
InvalidCastException
возникает при загрузке страницы с сообщением "Не удается привести объект типа "ASP.alternate_master", чтобы ввести "ASP.site_master".
Эти ошибки возникают из-за того, что Site.master
класс программной части включает в себя общедоступные события, свойства и методы, которые не определены в Alternate.master
. Часть разметки этих двух страниц имеет директиву @MasterType
, которая ссылается на Site.master
главную страницу.
<%@ MasterType VirtualPath="~/Site.master" %>
Кроме того, обработчик событий DetailsView ItemInserted
включает ~/Admin/AddProduct.aspx
в себя код, который приводит слабо типизированное Page.Master
свойство к объекту типа Site
. Директива @MasterType
(используется таким образом) и приведение в ItemInserted
обработчике событий тесно связывает ~/Admin/AddProduct.aspx
страницы с ~/Admin/Products.aspx
главной страницей Site.master
.
Чтобы разорвать эту жесткую связь, мы можем иметь Site.master
и Alternate.master
наследовать от общего базового класса, содержащего определения для общедоступных членов. После этого мы можем обновить директиву, чтобы ссылаться на этот общий базовый @MasterType
тип.
Создание настраиваемого класса эталонной страницы
Добавьте новый файл класса в папку App_Code
с именем BaseMasterPage.cs
и наследуйте ее.System.Web.UI.MasterPage
Нам нужно определить RefreshRecentProductsGrid
метод и GridMessageText
свойство, BaseMasterPage
но мы не можем просто переместить их туда Site.master
, так как эти элементы работают с веб-элементами управления, которые относятся к Site.master
главной странице ( RecentProducts
GridView и GridMessage
Label).
Необходимо настроить BaseMasterPage
таким образом, чтобы эти члены были определены там, но на самом деле реализуются производными классами BaseMasterPage
(Site.master
и Alternate.master
). Этот тип наследования возможен, помечая класс и его члены как abstract
. Короче говоря, добавление ключевого abstract
слова к этим двум членам объявляет, что BaseMasterPage
не реализовано RefreshRecentProductsGrid
и GridMessageText
, но что его производные классы будут.
Кроме того, необходимо определить PricesDoubled
событие BaseMasterPage
и предоставить средства производными классами для создания события. Шаблон, используемый в платформа .NET Framework для упрощения этого поведения, заключается в создании общедоступного события в базовом классе и добавлении virtual
защищенного метода с именемOnEventName
. Производные классы затем могут вызвать этот метод, чтобы вызвать событие или переопределить его для выполнения кода непосредственно перед или после вызова события.
Обновите BaseMasterPage
класс, чтобы он содержал следующий код:
using System; public abstract class BaseMasterPage : System.Web.UI.MasterPage
{
public event EventHandler PricesDoubled;
protected virtual void OnPricesDoubled(EventArgs e)
{
if (PricesDoubled != null)
PricesDoubled(this, e);
}
public abstract void RefreshRecentProductsGrid();
public abstract string GridMessageText
{
get;
set;
}
}
Затем перейдите к классу Site.master
code-behind и наследуйтесь от BaseMasterPage
него. Потому что BaseMasterPage
abstract
нам нужно переопределить эти abstract
члены здесь Site.master
. Добавьте ключевое override
слово в определения методов и свойств. Также обновите код, который вызывает PricesDoubled
событие в DoublePrice
обработчике событий Button Click
с вызовом метода базового класса OnPricesDoubled
.
После этих изменений Site.master
класс code-behind должен содержать следующий код:
public partial class Site : BaseMasterPage {
protected void Page_Load(object sender, EventArgs e)
{
DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd");
}
public override void RefreshRecentProductsGrid()
{
RecentProducts.DataBind();
}
public override string GridMessageText
{
get
{
return GridMessage.Text;
}
set
{
GridMessage.Text = value;
}
}
protected void DoublePrice_Click(object sender, EventArgs e)
{
// Double the prices
DoublePricesDataSource.Update();
// Refresh RecentProducts
RecentProducts.DataBind();
// Raise the PricesDoubled event
base.OnPricesDoubled(EventArgs.Empty);
}
}
Кроме того, необходимо обновить Alternate.master
класс кода программной части для производных от BaseMasterPage
двух элементов и переопределить их abstract
. Но поскольку Alternate.master
не содержит GridView, в котором перечислены последние продукты или метка, отображающая сообщение после добавления нового продукта в базу данных, эти методы не должны ничего делать.
public partial class Alternate : BaseMasterPage
{
public override void RefreshRecentProductsGrid()
{
// Do nothing
}
public override string GridMessageText
{
get
{
return string.Empty;
}
set
{
// Do nothing
}
}
}
Ссылка на базовый класс главной страницы
Теперь, когда мы завершили BaseMasterPage
класс и расширяли две главные страницы, мы завершаем его, чтобы обновить ~/Admin/AddProduct.aspx
и ~/Admin/Products.aspx
страницы, чтобы ссылаться на этот общий тип. Начните с изменения @MasterType
директивы на обеих страницах:
<%@ MasterType VirtualPath="~/Site.master" %>
Кому:
<%@ MasterType TypeName="BaseMasterPage" %>
Вместо ссылки на путь к @MasterType
файлу свойство теперь ссылается на базовый тип (BaseMasterPage
). Следовательно, строго типизированное Master
свойство, используемое в классах кода обеих страниц, теперь имеет тип (вместо типа BaseMasterPage
Site
). С этим изменением на месте пересматривается ~/Admin/Products.aspx
. Ранее это привело к ошибке приведения, так как страница настроена на использование главной Alternate.master
страницы, но @MasterType
директива ссылается на Site.master
файл. Но теперь страница отрисовывается без ошибок. Это связано с тем, что эталонная Alternate.master
страница может быть приведение к объекту типа BaseMasterPage
(так как он расширяет его).
Есть одно небольшое изменение, которое необходимо внести ~/Admin/AddProduct.aspx
. Обработчик событий элемента управления ItemInserted
DetailsView использует как строго типизированное Master
свойство, так и свободно типизированное Page.Master
свойство. Исправлена строго типизированная ссылка при обновлении @MasterType
директивы, но нам все равно нужно обновить слабо типизированную ссылку. Замените следующую строку кода:
Site myMasterPage = Page.Master as Site;
С помощью следующего, который приводит Page.Master
к базовому типу:
BaseMasterPage myMasterPage = Page.Master as BaseMasterPage;
Шаг 4. Определение главной страницы для привязки к страницам содержимого
В настоящее время наш BasePage
класс устанавливает все свойства страниц контента MasterPageFile
на жестко закодированное значение на этапе предварительной версии жизненного цикла страницы. Этот код можно обновить, чтобы создать эталонную страницу на некоторых внешних факторах. Возможно, эталонная страница для загрузки зависит от настроек текущего пользователя, вошедшего в систему. В этом случае нам потребуется написать код в методе OnPreInit
, BasePage
который ищет параметры главной страницы пользователя.
Давайте создадим веб-страницу, которая позволяет пользователю выбрать главную страницу для использования или Site.master
Alternate.master
сохранить этот выбор в переменной сеанса. Начните с создания новой веб-страницы в корневом каталоге с именем ChooseMasterPage.aspx
. При создании этой страницы (или любой другой страницы содержимого отсюда) ее не нужно привязать к главной странице, так как эталонная страница устанавливается программным образом BasePage
. Однако если вы не привязываете новую страницу к главной странице, то декларативная разметка новой страницы по умолчанию содержит веб-форму и другое содержимое, предоставленное главной страницей. Вам потребуется вручную заменить эту разметку соответствующими элементами управления содержимым. По этой причине мне проще привязать новую страницу ASP.NET к главной странице.
Примечание.
Так как Site.master
и один и Alternate.master
тот же набор элементов управления ContentPlaceHolder, не имеет значения главной страницы при создании новой страницы содержимого. Для согласованности я бы предложил использовать Site.master
.
Рис. 05. Добавление новой страницы содержимого на веб-сайт (щелкните, чтобы просмотреть изображение полного размера)
Web.sitemap
Обновите файл, чтобы включить запись для этого занятия. Добавьте следующую разметку под <siteMapNode>
главной страницой и ASP.NET урок AJAX:
<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />
Прежде чем добавлять содержимое на ChooseMasterPage.aspx
страницу, необходимо обновить класс кода страницы таким образом, чтобы он был производным от BasePage
(а не System.Web.UI.Page
). Затем добавьте элемент управления DropDownList на страницу, задайте для него значение свойства ID
MasterPageChoice
и добавьте два ListItems со Text
значениями ~/Site.master и ~/Alternate.master.
Добавьте веб-элемент управления Button на страницу и задайте для нее значения 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 void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["MyMasterPage"] != null)
{
ListItem li = MasterPageChoice.Items.FindByText(Session["MyMasterPage"].ToString());
if (li != null)
li.Selected = true;
}
}
}
Приведенный выше код выполняется только на первой странице (а не на последующих обратных страницах). Сначала проверяет, существует ли переменная MyMasterPage
сеанса. Если это так, он пытается найти соответствующий ListItem в MasterPageChoice
DropDownList. Если найден соответствующий ListItem, для свойства Selected
задано значение true
.
Нам также нужен код, который сохраняет выбор пользователя в переменную сеанса MyMasterPage
. Создайте обработчик событий для SaveLayout
события Button Click
и добавьте следующий код:
protected void SaveLayout_Click(object sender, EventArgs e)
{
Session["MyMasterPage"] = MasterPageChoice.SelectedValue;
Response.Redirect("ChooseMasterPage.aspx");
}
Примечание.
К тому времени, когда Click
обработчик событий выполняется при обратной отправке, эталонная страница уже выбрана. Поэтому раскрывающийся список пользователя не будет в силе до следующей страницы. Браузер Response.Redirect
принудительно запрашивает ChooseMasterPage.aspx
повторно.
ChooseMasterPage.aspx
После завершения страницы наша окончательная задача состоит в том, чтобы BasePage
назначить MasterPageFile
свойство в зависимости от значения переменной сеансаMyMasterPage
. Если переменная сеанса не задана BasePage
по умолчанию Site.master
.
protected override void OnPreInit(EventArgs e)
{
SetMasterPageFile();
base.OnPreInit(e);
}
protected virtual void SetMasterPageFile()
{
this.MasterPageFile = GetMasterPageFileFromSession();
}
protected string GetMasterPageFileFromSession()
{
if (Session["MyMasterPage"] == null)
return "~/Site.master";
else
return Session["MyMasterPage"].ToString();
}
Примечание.
Я переместил код, который назначает Page
свойство объекта MasterPageFile
из OnPreInit
обработчика событий и в два отдельных метода. Этот первый метод SetMasterPageFile
присваивает MasterPageFile
свойству значение, возвращаемое вторым методом. GetMasterPageFileFromSession
Я сделал метод virtual
таким образом, чтобы будущие SetMasterPageFile
классы, которые BasePage
могут дополнительно переопределить его для реализации пользовательской логики при необходимости. Мы увидим пример переопределения BasePage
SetMasterPageFile
свойства в следующем руководстве.
В этом коде посетите страницу ChooseMasterPage.aspx
. Site.master
Изначально выбрана эталонная страница (см. рис. 6), но пользователь может выбрать другую главную страницу из раскрывающегося списка.
Рис. 06. Страницы контента отображаются с помощью главной Site.master
страницы (щелкните, чтобы просмотреть изображение полного размера)
Рис. 07. Теперь страницы содержимого отображаются с помощью главной Alternate.master
страницы (щелкните, чтобы просмотреть изображение полного размера)
Итоги
При посещении страницы содержимого элементы управления содержимым смешаются с элементами управления ContentPlaceHolder главной страницы. Главная страница страницы содержимого обозначается свойством Page
класса MasterPageFile
, которое назначается @Page
атрибуту директивы MasterPageFile
во время этапа инициализации. Как показано в этом руководстве, мы можем назначить значение MasterPageFile
свойству до конца этапа PreInit. При программном указании главной страницы открывается дверь для более сложных сценариев, например динамической привязки страницы содержимого к главной странице на основе внешних факторов.
Счастливое программирование!
Дополнительные материалы
Дополнительные сведения о разделах, описанных в этом руководстве, см. в следующих ресурсах:
- Обзор жизненного цикла страницы ASP.NET
- Общие сведения о темах и кожах ASP.NET
- Главные страницы: советы, рекомендации и ловушки
- Темы в ASP.NET
Об авторе
Скотт Митчелл, автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Сэмс Учит себя ASP.NET 3,5 в 24 часах. Скотт можно получить по mitchell@4GuysFromRolla.com адресу или через свой блог.http://ScottOnWriting.NET
Особое спасибо
Эта серия учебников была проверена многими полезными рецензентами. Ведущий рецензент для этого руководства был Таким Баньерджи. Хотите просмотреть мои предстоящие статьи MSDN? Если да, выбросить меня линию в mitchell@4GuysFromRolla.com