Программное указание эталонной страницы (C#)
Проверяет настройку страницы master содержимого программным способом с помощью обработчика событий PreInit.
Введение
После первого примера в статье Создание макета Site-Wide с помощью главных страниц все страницы контента декларативно ссылаются на свою master страницу с помощью атрибута MasterPageFile
в директиве @Page
. Например, следующая @Page
директива связывает страницу содержимого со страницей Site.master
master :
<%@ Page Language="C#" MasterPageFile="~/Site.master" ... %>
КлассPage
в System.Web.UI
пространстве имен содержит MasterPageFile
свойство , которое возвращает путь к странице master страницы содержимого. Именно это свойство задается директивой @Page
. Это свойство также можно использовать для программного указания страницы master содержимого. Этот подход полезен, если вы хотите динамически назначать страницу master на основе внешних факторов, таких как пользователь, посещающий страницу.
В этом руководстве мы добавим вторую страницу master на веб-сайт и динамически решаем, какую страницу master использовать во время выполнения.
Шаг 1. Обзор жизненного цикла страницы
Всякий раз, когда на веб-сервер поступает запрос на страницу ASP.NET, которая является страницей содержимого, подсистема ASP.NET должна объединить элементы управления контентом страницы в соответствующие элементы управления ContentPlaceHolder master страницы. Это слияние создает единую иерархию элементов управления, которая затем может проходить через типичный жизненный цикл страницы.
На рисунке 1 показана эта слияние. На шаге 1 на рис. 1 показано начальное содержимое и иерархии master элементов управления страницы. В конце этапа PreInit элементы управления контентом на странице добавляются в соответствующий объект ContentPlaceHolders на странице master (шаг 2). После этого слияния страница master служит корнем иерархии плавленного элемента управления. Затем эта слитая иерархия элементов управления добавляется на страницу для создания окончательной иерархии элементов управления (шаг 3). Результатом является то, что иерархия элементов управления страницы включает в себя иерархию слитых элементов управления.
Рис. 01. Иерархии элементов управления главной страницы и страницы содержимого объединяются на этапе preInit (щелкните для просмотра полноразмерного изображения)
Шаг 2. ЗаданиеMasterPageFile
свойства из кода
Какие master страницы участвуют в этом слиянии, зависит от значения Page
свойства объектаMasterPageFile
. Задание атрибута MasterPageFile
в директиве @Page
имеет чистый эффект назначения Page
MasterPageFile
свойства на этапе инициализации, который является самым первым этапом жизненного цикла страницы. Можно также задать это свойство программным способом. Однако крайне важно, чтобы это свойство было задано до слияния на рис. 1.
В начале этапа Page
PreInit объект вызывает событиеPreInit
и вызывает методOnPreInit
. Чтобы задать master страницу программным способом, можно либо создать обработчик событий для PreInit
события, либо переопределить OnPreInit
метод . Давайте рассмотрим оба метода.
Начните с открытия Default.aspx.cs
файла класса кода программной части для домашней страницы нашего сайта. Добавьте обработчик событий для события страницы 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
свойство . В этом примере давайте не задавайте master страницу на определенной странице, а из BasePage
. Помните, что мы создали пользовательский класс базовой страницы (BasePage
) еще в руководстве Указание заголовка, метатегов и других заголовков HTML в главной странице . В настоящее BasePage
время переопределяет Page
метод класса OnLoadComplete
, где он задает свойство страницы Title
на основе данных карты сайта. Давайте обновимBasePage
, чтобы переопределить OnPreInit
метод для программного указания страницы master.
protected override void OnPreInit(EventArgs e)
{
this.MasterPageFile = "~/Site.master";
base.OnPreInit(e);
}
Так как все страницы содержимого являются производными от BasePage
, все они теперь имеют master страницы, назначенные программным способом. На этом этапе 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 в Designer. Если вернуться к Default.aspx
в Visual Studio и перейти к Designer появится сообщение "Ошибка главной страницы: страница содержит элементы управления, требующие ссылки на эталонную страницу, но не указан" (см. рис. 2).
Короче говоря, необходимо оставить MasterPageFile
атрибут в директиве , @Page
чтобы использовать широкие возможности разработки в Visual Studio.
@Page для отображения представления конструктора" />
Рис. 02. Visual Studio использует @Page
атрибут директивы для отображения представления конструктора MasterPageFile
(щелкните, чтобы просмотреть полноразмерное изображение)
Шаг 3. Создание альтернативной главной страницы
Так как master страницу содержимого можно задать программно во время выполнения, можно динамически загружать определенную страницу master на основе некоторых внешних критериев. Эта функция может быть полезна в ситуациях, когда макет сайта должен меняться в зависимости от пользователя. Например, веб-приложение подсистемы блога может позволить пользователям выбирать макет для своего блога, где каждый макет связан с другой master страницей. Во время выполнения, когда посетитель просматривает блог пользователя, веб-приложению потребуется определить макет блога и динамически связать соответствующую страницу master со страницей содержимого.
Давайте рассмотрим, как динамически загружать страницу master во время выполнения на основе некоторых внешних критериев. Наш веб-сайт в настоящее время содержит только одну страницу master (Site.master
). Нам нужна другая страница master, чтобы проиллюстрировать выбор страницы master во время выполнения. Этот шаг посвящен созданию и настройке новой страницы master. На шаге 4 рассматривается определение master страницы для использования во время выполнения.
Создайте новую страницу master в корневой папке с именем Alternate.master
. Также добавьте новую таблицу стилей на веб-сайт с именем AlternateStyles.css
.
Рис. 03. Добавление другой главной страницы и CSS-файла на веб-сайт (щелкните для просмотра полноразмерного изображения)
Я разработал страницу Alternate.master
master, чтобы заголовок отображался в верхней части страницы, по центру и на фоне военно-морского флота. Я отбрасывал левый столбец и переместил это содержимое под MainContent
элементом управления ContentPlaceHolder, который теперь охватывает всю ширину страницы. Кроме того, я переместил неупорядоченный список уроков и заменил его горизонтальным списком над MainContent
. Я также обновил шрифты и цвета, используемые на странице master (и, в расширении, на страницах содержимого). На рисунке 4 показано Default.aspx
использование страницы Alternate.master
master.
Примечание
ASP.NET включает возможность определения тем. Тема — это коллекция изображений, CSS-файлов и параметров свойств веб-элемента управления, связанных со стилем, которые можно применить к странице во время выполнения. Темы — это путь, если макеты сайта отличаются только отображаемыми изображениями и правилами CSS. Если макеты отличаются более существенно, например с использованием различных веб-элементов управления или с совершенно другим макетом, вам потребуется использовать отдельные master страницы. Дополнительные сведения о темах см. в разделе Дальнейшее чтение в конце этого руководства.
Рис. 04. Наши страницы содержимого теперь могут использовать новый внешний вид (щелкните для просмотра полноразмерного изображения)
При слиянии разметки страниц master и содержимого класс проверяет, MasterPage
ссылается ли каждый элемент управления Контентом на странице содержимого на ContentPlaceHolder на странице master. Исключение возникает при обнаружении элемента управления контентом, который ссылается на несуществующий ContentPlaceHolder. Иными словами, крайне важно, чтобы страница master, назначаемая странице содержимого, была contentPlaceHolder для каждого элемента управления контентом на странице содержимого.
Страница Site.master
master содержит четыре элемента управления ContentPlaceHolder:
head
MainContent
QuickLoginUI
LeftColumnContent
Некоторые страницы содержимого на нашем веб-сайте содержат только один или два элемента управления контентом; другие включают элемент управления Контент для каждого из доступных ContentPlaceHolders. Если наша новая страница master (Alternate.master
) может когда-либо быть назначена тем страницам содержимого, которые имеют элементы управления контентом для всех ContentPlaceHolders в Site.master
, важно также включить те же элементы управления ContentPlaceHolder, что Alternate.master
и Site.master
.
Alternate.master
Чтобы страница master выглядела аналогично моей (см. рис. 4), начните с определения стилей страницы master в таблице стилей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
значениями, что и элементы управления ContentPlaceHolder в Site.master
. Кроме того, он включает элемент управления 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>
Тестирование новой главной страницы
Чтобы протестировать эту новую master странице обновите BasePage
метод классаOnPreInit
, чтобы свойству MasterPageFile
было присвоено значение "~/Alternate.master", а затем посетите веб-сайт. Каждая страница должна работать без ошибок, за исключением двух: ~/Admin/AddProduct.aspx
и ~/Admin/Products.aspx
. Добавление продукта в DetailsView в ~/Admin/AddProduct.aspx
приводит к получению NullReferenceException
из строки кода, которая пытается задать свойство страницы GridMessageText
master. При посещении ~/Admin/Products.aspx
InvalidCastException
возникает при загрузке страницы сообщение: "Не удается привести объект типа "ASP.alternate_master" к типу "ASP.site_master".
Эти ошибки возникают из-за того Site.master
, что класс кода программной части содержит открытые события, свойства и методы, которые не определены в Alternate.master
. Часть разметки этих двух страниц имеет директиву@MasterType
, которая ссылается на Site.master
master страницу.
<%@ MasterType VirtualPath="~/Site.master" %>
Кроме того, обработчик событий DetailsView ItemInserted
в ~/Admin/AddProduct.aspx
содержит код, который приводит свойство слабо типизированного Page.Master
к объекту типа Site
. Директива @MasterType
(используется таким образом) и приведение в обработчике ItemInserted
событий тесно связаны ~/Admin/AddProduct.aspx
страницы и ~/Admin/Products.aspx
со страницей Site.master
master.
Чтобы разорвать эту тесную связь, мы можем получить Site.master
и Alternate.master
наследовать от общего базового класса, который содержит определения для открытых членов. После этого можно обновить директиву для @MasterType
ссылки на этот общий базовый тип.
Создание настраиваемого класса базовой главной страницы
Добавьте новый файл класса в папку с App_Code
именем BaseMasterPage.cs
и наследуйте его от System.Web.UI.MasterPage
. Нам нужно определить RefreshRecentProductsGrid
метод и GridMessageText
свойство в BaseMasterPage
, но мы не можем просто переместить их оттудаSite.master
, так как эти элементы работают с веб-элементами управления, характерными для Site.master
страницы 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
кода программной части и наследуйте его от BaseMasterPage
. Потому что BaseMasterPage
нам нужно переопределить эти abstract
члены здесь, в Site.master
.abstract
override
Добавьте ключевое слово в определения метода и свойства. Кроме того, обновите код, который вызывает PricesDoubled
событие в DoublePrice
обработчике Click
событий Button, вызвав метод базового класса OnPricesDoubled
.
После этих изменений Site.master
класс кода программной части должен содержать следующий код:
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
и расширили его две страницы master, наш последний шаг — обновить ~/Admin/AddProduct.aspx
страницы и , ~/Admin/Products.aspx
чтобы они ссылались на этот распространенный тип. Начните с изменения директивы на @MasterType
обеих страницах с:
<%@ MasterType VirtualPath="~/Site.master" %>
В:
<%@ MasterType TypeName="BaseMasterPage" %>
Вместо ссылки на путь к файлу @MasterType
свойство теперь ссылается на базовый тип (BaseMasterPage
). Следовательно, строго типизированное Master
свойство, используемое в классах кода программной части обеих страниц, теперь имеет тип BaseMasterPage
(а не тип Site
). С этим изменением на месте вернитесь к ~/Admin/Products.aspx
. Ранее это приводило к ошибке приведения, так как страница настроена для использования Alternate.master
master страницы, но директива @MasterType
ссылалась на Site.master
файл. Но теперь страница отображается без ошибок. Это связано с тем Alternate.master
, что 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
содержимого как жестко закодированное значение на этапе PreInit жизненного цикла страницы. Мы можем обновить этот код, чтобы на странице master учитывались некоторые внешние факторы. Возможно, загрузка страницы master зависит от предпочтений текущего пользователя, выполнившего вход. В этом случае нам потребуется написать код в методе OnPreInit
в BasePage
, который ищет параметры страницы master текущего пользователя.
Давайте создадим веб-страницу, которая позволяет пользователю выбрать, какую master страницу использовать ( Site.master
или Alternate.master
) и сохранить этот вариант в переменной сеанса. Начните с создания новой веб-страницы в корневом каталоге с именем ChooseMasterPage.aspx
. При создании этой страницы (или любых других страниц содержимого в настоящее время) ее не нужно привязывать к master странице, так как master страница задается программным способом в BasePage
. Однако если не привязать новую страницу к master странице, декларативная разметка новой страницы по умолчанию будет содержать веб-форму и другое содержимое, предоставляемое master страницей. Вам потребуется вручную заменить эту разметку соответствующими элементами управления контентом. По этой причине мне проще привязать новую страницу ASP.NET к master странице.
Примечание
Так как Site.master
и Alternate.master
имеют одинаковый набор элементов управления ContentPlaceHolder, не имеет значения, какую master страницу вы выбираете при создании новой страницы содержимого. Для обеспечения согласованности я бы предложил использовать .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 Web и задайте для его 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 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
Session. Если это так, он пытается найти соответствующий ListItem в MasterPageChoice
DropDownList. Если найден соответствующий Объект ListItem, его Selected
свойству true
присваивается значение .
Нам также нужен код, который сохраняет выбор пользователя в переменной MyMasterPage
Session. Создайте обработчик событий для SaveLayout
события Button Click
и добавьте следующий код:
protected void SaveLayout_Click(object sender, EventArgs e)
{
Session["MyMasterPage"] = MasterPageChoice.SelectedValue;
Response.Redirect("ChooseMasterPage.aspx");
}
Примечание
К тому времени, когда Click
обработчик событий будет выполняться при обратной отправке, страница master уже была выбрана. Таким образом, выбор раскрывающегося списка пользователя не будет действовать до следующего посещения страницы. Заставляет Response.Redirect
браузер повторно запрашивать ChooseMasterPage.aspx
.
ChooseMasterPage.aspx
После завершения страницы наша конечная задача — BasePage
назначить MasterPageFile
свойство на основе значения переменной MyMasterPage
Session. Если переменная Session не задана, по умолчанию имеет 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
страница master (см. рис. 6), но пользователь может выбрать другую страницу master из раскрывающегося списка.
Рис. 06. Страница содержимого отображается с помощью главной Site.master
страницы (щелкните для просмотра полноразмерного изображения)
Рис. 07. Страницы содержимого теперь отображаются с помощью главной Alternate.master
страницы (щелкните для просмотра полноразмерного изображения)
Сводка
При посещении страницы содержимого ее элементы управления контентом сливаются с элементами управления ContentPlaceHolder master страницы. Страница master страницы содержимого обозначается свойством Page
класса MasterPageFile
, которое назначается атрибуту @Page
директивы MasterPageFile
на этапе инициализации. Как показано в этом руководстве, мы можем присвоить значение свойству MasterPageFile
до завершения этапа PreInit. Возможность программно указать страницу master открывает возможности для более сложных сценариев, таких как динамическая привязка страницы содержимого к странице master на основе внешних факторов.
Счастливое программирование!
Дополнительные материалы
Дополнительные сведения по темам, рассматриваемым в этом руководстве, см. в следующих ресурсах:
- Схема жизненного цикла страницы ASP.NET
- Обзор жизненного цикла страницы ASP.NET
- Общие сведения о темах и обложках ASP.NET
- Эталонные страницы: советы, рекомендации и ловушки
- Темы в ASP.NET
Об авторе
Скотт Митчелл (Scott Mitchell), автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 3,5 в 24 часа. Скотт можно связаться по адресу mitchell@4GuysFromRolla.com или через его блог по адресу http://ScottOnWriting.NET.
Отдельная благодарность
Эта серия учебников была проверена многими полезными рецензентами. Ведущим рецензентом этого руководства был Сучи Банерджи. Хотите ознакомиться с моими предстоящими статьями MSDN? Если да, бросить мне линию на mitchell@4GuysFromRolla.com