Вложенные эталонные страницы (VB)

Скотт Митчелл

Показывает, как вложить одну master страницу в другую.

Введение

В ходе работы с последними девятью руководствами мы увидели, как реализовать макет на уровне сайта с master страниц. В двух словах, master страницы позволяют нам, разработчику страниц, определять общую разметку на странице master вместе с конкретными регионами, которые можно настраивать на странице контента по содержимому. Элементы управления ContentPlaceHolder на странице master указывают настраиваемые регионы. Настраиваемая разметка для элементов управления ContentPlaceHolder определяется на странице содержимого с помощью элементов управления Контентом.

Методы master страниц, которые мы изучили до сих пор, отлично подходят, если у вас есть один макет, используемый на всем сайте. Однако многие крупные веб-сайты имеют макет сайта, который настраивается в разных разделах. Например, рассмотрим приложение для здравоохранения, используемое персоналом больницы для управления информацией о пациентах, действиями и выставлением счетов. В этом приложении может быть три типа веб-страниц:

  • Страницы, относящиеся к сотрудникам, на которых сотрудники могут обновлять доступность, просматривать расписания или запрашивать время отпуска.
  • Страницы, относящиеся к конкретному пациенту, на которых сотрудники просматривают или редактируют информацию о конкретном пациенте.
  • Страницы, относящиеся к выставлению счетов, на которых бухгалтеры просматривают текущие состояния претензий и финансовые отчеты.

У каждой страницы может быть общий макет, например меню вверху и ряд часто используемых ссылок в нижней части. Однако на страницах, относящихся к персоналу, пациенту и выставлению счетов, может потребоваться настроить этот универсальный макет. Например, все страницы, относящиеся к персоналу, должны содержать календарь и список задач, в которых отображаются сведения о доступности и ежедневном расписании пользователя, выполнившего вход в систему. Возможно, на всех страницах конкретного пациента должны отображаться имя, адрес и сведения о страховании для пациента, данные которого редактируются.

Такие настраиваемые макеты можно создавать с помощью вложенных master страниц. Для реализации приведенного выше сценария мы начнем с создания master страницы, которая определяет макет на уровне сайта, меню и содержимое нижнего колонтитула, а ContentPlaceHolders определяет настраиваемые регионы. Затем мы создадим три вложенные master страницы, по одной для каждого типа веб-страницы. Каждая вложенная страница master будет определять содержимое среди типов страниц контента, использующих страницу master. Другими словами, вложенная страница master для страниц содержимого для конкретного пациента будет включать разметку и программную логику для отображения информации об редактируемом пациенте. При создании новой страницы для конкретного пациента мы привязываем ее к этой вложенной странице master.

В начале работы с этим руководством рассматриваются преимущества вложенных master страниц. Затем в ней показано, как создавать и использовать вложенные страницы master.

Примечание

Вложенные master страницы стали возможными с версии 2.0 платформа .NET Framework. Однако в Visual Studio 2005 не включена поддержка вложенных master страниц во время разработки. Хорошей новостью является то, что Visual Studio 2008 предлагает широкие возможности разработки вложенных страниц master. Если вы заинтересованы в использовании вложенных master страниц, но по-прежнему используете Visual Studio 2005, проверка запись в блоге Скотта ГатриСоветы для вложенных эталонных страниц в СРЕДЕ разработки VS 2005.

Преимущества вложенных главных страниц

Многие веб-сайты имеют всеобъемлющий дизайн сайта, а также более настраиваемые макеты, характерные для определенных типов страниц. Например, в демонстрационном веб-приложении мы создали раздел "Администрирование" (страницы в папке ~/Admin ). В настоящее время веб-страницы в ~/Admin папке используют ту же master страницу, что и те страницы, которые не находятся в разделе администрирования (а именно, Site.master или Alternate.master, в зависимости от выбора пользователя).

Примечание

На данный момент сделайте вид, что наш сайт имеет только одну master страницу, Site.master. Далее в этом руководстве мы рассмотрим использование вложенных master страниц с двумя (или более) master страницами, начиная с "Использование вложенной главной страницы для раздела администрирования".

Представьте, что нас попросили настроить макет страниц администрирования, чтобы включить дополнительные сведения или ссылки, которые в противном случае не будут присутствовать на других страницах сайта. Существует четыре метода реализации этого требования:

  1. Вручную добавьте сведения об администрировании и ссылки на каждую страницу содержимого в папке ~/Admin .
  2. Site.master Обновите страницу master, включив сведения и ссылки для раздела "Администрирование", а затем добавьте на страницу master код для отображения или скрытия этих разделов в зависимости от того, просматривается ли одна из страниц администрирования.
  3. Создайте страницу master специально для раздела Администрирование, скопируйте разметку из Site.master, добавьте сведения и ссылки для раздела Администрирование, а затем обновите страницы содержимого в ~/Admin папке, чтобы использовать эту новую страницу master.
  4. Создайте вложенную страницу master, которая привязывается к Site.master и содержит страницы содержимого в ~/Admin папке, используя эту новую вложенную страницу master. Эта вложенная страница master будет содержать только дополнительные сведения и ссылки, относящиеся к страницам администрирования, и не потребуется повторять разметку, уже определенную в Site.master.

Первый вариант является наименее приемлемым. Весь смысл использования master страниц заключается в том, чтобы отойти от необходимости вручную копировать и вставлять общую разметку на новые страницы ASP.NET. Второй вариант является приемлемым, но делает приложение менее пригодным для обслуживания, так как оно обнаружает master страниц с разметкой, которая отображается лишь иногда и требует от разработчиков, редактируемых master страницы, чтобы обойти эту разметку и помнить, когда именно отображается определенная разметка, а не когда она скрыта. Этот подход будет менее приемлемым, так как настройки из все большего числа типов веб-страниц должны быть вмещаются в эту одну master страницу.

Третий вариант устраняет беспорядок и сложность проблем, возникающих при использовании второго варианта. Однако недостаток третьего варианта main заключается в том, что он требует копирования и вставки общего макета на Site.master новую страницу master раздела "Администрирование". Если позже мы решим изменить макет на уровне сайта, мы не забудьте изменить его в двух местах.

Четвертый вариант, вложенный master страниц, дает нам лучшие из второго и третьего вариантов. Сведения о макете на уровне сайта хранятся в одном файле ( странице master верхнего уровня), в то время как содержимое, относящегося к определенным регионам, разделяется на разные файлы.

В этом руководстве рассматривается создание и использование простой вложенной страницы master. Мы создаем новую страницу master верхнего уровня, две вложенные страницы master и две страницы содержимого. Начиная с раздела "Использование вложенной главной страницы для раздела администрирования", мы рассмотрим обновление существующей архитектуры страниц master, чтобы включить использование вложенных master страниц. В частности, мы создаем вложенную страницу master и используем ее для добавления дополнительного пользовательского содержимого для страниц содержимого в папке~/Admin.

Шаг 1. Создание простой главной страницы Top-Level

Создание вложенной master на основе одной из существующих страниц master, а затем обновление существующей страницы контента для использования этой новой вложенной master страницы вместо страницы master верхнего уровня влечет за собой определенную сложность, так как существующие страницы контента уже ожидают определенные элементы управления ContentPlaceHolder, определенные на странице master верхнего уровня. Поэтому вложенная страница master также должна содержать те же элементы управления ContentPlaceHolder с одинаковыми именами. Кроме того, наше демонстрационное приложение имеет две страницы master (Site.master и Alternate.master), которые динамически назначаются странице содержимого на основе предпочтений пользователя, что еще больше усложняет эту задачу. Мы рассмотрим обновление существующего приложения для использования вложенных master страниц далее в этом руководстве, но сначала рассмотрим простой пример вложенных master страниц.

Создайте папку с именем NestedMasterPages , а затем добавьте в нее Simple.masterновый файл подкачки master . (Снимок экрана с Обозреватель решений после добавления этой папки и файла см. на рисунке 1.) Перетащите AlternateStyles.css файл таблицы стилей из Обозреватель решений на Designer. При этом элемент добавляется <link> в файл таблицы стилей в элементе <head> , после чего разметка элемента master страницы <head> должна выглядеть следующим образом:

<head runat="server"> 
 <title>Untitled Page</title> 
 <asp:ContentPlaceHolder id="head" runat="server"> 
 </asp:ContentPlaceHolder>
 <link href="../AlternateStyles.css" rel="stylesheet" type="text/css" /> 
</head>

Затем добавьте следующую разметку в веб-форму :Simple.master

<div id="topContent"> 
 <asp:HyperLink ID="lnkHome" runat="server" 
 NavigateUrl="~/NestedMasterPages/Default.aspx" 
 Text="Nested Master Pages Tutorial (Simple)" /> 
</div> 
<div id="mainContent"> 
 <asp:ContentPlaceHolder id="MainContent" runat="server"> 
 </asp:ContentPlaceHolder>
</div>

Эта разметка отображает ссылку "Вложенные главные страницы (простые)" в верхней части страницы крупным белым шрифтом на фоне военно-морского флота. Под ним находится MainContent ContentPlaceHolder. На рисунке 1 показана Simple.master страница master при загрузке в Designer Visual Studio.

Страница простая точка master master при загрузке в Designer Visual Studio.

Рис. 01. Вложенная эталонная страница определяет содержимое страниц в разделе администрирования (щелкните для просмотра полноразмерного изображения)

Шаг 2. Создание простой вложенной главной страницы

Simple.master содержит два элемента управления ContentPlaceHolder: MainContent ContentPlaceHolder, добавленный в веб-форму, и head ContentPlaceHolder в элементе <head> . Если бы мы создали страницу содержимого и привяжем ее к Simple.master странице содержимого, у нас будет два элемента управления Контентом, ссылающиеся на два ContentPlaceHolders. Аналогичным образом, если мы создадим вложенную страницу master и привязываем ее к Simple.master , то у вложенной страницы master будет два элемента управления Содержимое.

Давайте добавим новую вложенную страницу master в папку NestedMasterPages с именем SimpleNested.master. Щелкните папку правой NestedMasterPages кнопкой мыши и выберите команду Добавить новый элемент. Откроется диалоговое окно Добавление нового элемента, показанное на рис. 2. Выберите тип шаблона эталонной страницы и введите имя новой страницы master. Чтобы указать, что новая страница master должна быть вложенной страницей master, проверка флажок "Выбрать страницу master".

Затем нажмите кнопку Добавить. Откроется то же диалоговое окно Выбор главной страницы, которое отображается при привязке страницы содержимого к master странице (см. рис. 3). Выберите страницу Simple.master master в папке NestedMasterPages и нажмите кнопку ОК.

Примечание

Если вы создали веб-сайт ASP.NET, используя модель проекта веб-приложения вместо модели проекта веб-сайта, флажок "Выбрать master страницу" не будет отображаться в диалоговом окне Добавление нового элемента, показанном на рис. 2. Чтобы создать вложенную страницу master при использовании модели проекта веб-приложения, необходимо выбрать шаблон вложенной главной страницы (вместо шаблона главной страницы). После выбора шаблона вложенной главной страницы и нажатия кнопки Добавить появится то же диалоговое окно Выбор главной страницы, как показано на рисунке 3.

Установите флажок Select master page (Выбор страницы master), чтобы добавить вложенную главную страницу

Рис. 02. Установите флажок "Выбрать master страницу", чтобы добавить вложенную главную страницу (щелкните для просмотра полноразмерного изображения)

Привяжите вложенную главную страницу к элементу Simple. Эталонная страница master

Рис. 03. Привязка вложенной главной страницы к главной Simple.master странице (щелкните для просмотра полноразмерного изображения)

Декларативная разметка вложенной страницы master, показанная ниже, содержит два элемента управления Content, ссылающиеся на два элемента управления ContentPlaceHolder верхнего уровня master страницы.

<%@ Master Language="VB" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNested.master.vb" Inherits="NestedMasterPages_SimpleNested" %> 
 <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> 
 </asp:Content> 
 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> 
 </asp:Content>

<%@ Master %> За исключением директивы , начальная декларативная разметка вложенной master страницы идентична разметке, которая изначально создается при привязке страницы содержимого к той же странице master верхнего уровня. Как и директива страницы содержимого<%@ Master %>, директива <%@ Page %> здесь содержит атрибут , указывающий MasterPageFile родительскую страницу master вложенной master страницы. Разница main между вложенной страницей master и страницей содержимого, привязанной к одной и той же странице master верхнего уровня, заключается в том, что вложенная страница master может содержать элементы управления ContentPlaceHolder. Элементы управления ContentPlaceHolder вложенной master страницы определяют регионы, в которых страницы содержимого могут настраивать разметку.

Обновите эту вложенную master страницу, чтобы на ней отображался текст "Hello, from SimpleNested!" в элементе управления Контент, соответствующем элементу MainContent управления ContentPlaceHolder.

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> 
 <p>Hello, from SimpleNested!</p>
</asp:Content>

После добавления сохраните вложенную страницу master, а затем добавьте новую страницу содержимого в NestedMasterPages папку с именем Default.aspxи привяжите SimpleNested.master ее к странице master. При добавлении этой страницы вы можете быть удивлены тем, что она не содержит элементов управления содержимым (см. рис. 4)! Страница содержимого может получить доступ только к своей родительской master ContentPlaceHolders страницы. SimpleNested.masterне содержит элементов управления ContentPlaceHolder; Поэтому любая страница содержимого, привязанная к этой master странице, не может содержать элементы управления контентом.

Страница

Рис. 04. Страница нового содержимого не содержит элементов управления содержимым (щелкните для просмотра полноразмерного изображения)

Нам нужно обновить вложенную страницу master (SimpleNested.master), чтобы включить элементы управления ContentPlaceHolder. Как правило, вы хотите, чтобы вложенные страницы master включали ContentPlaceHolder для каждого ContentPlaceHolder, определенного его родительской master страницей, тем самым позволяя ее дочерней странице master или контентной странице работать с любыми элементами управления ContentPlaceHolder верхнего уровня master страницы.

Обновите страницу SimpleNested.master master, чтобы включить ContentPlaceHolder в два элемента управления Контент. Присвойте элементам управления ContentPlaceHolder то же имя, что и элементу управления ContentPlaceHolder, на которое ссылается элемент управления Контентом. То есть добавьте элемент управления ContentPlaceHolder с именем MainContent в элемент управления Контент в SimpleNested.master , который ссылается на MainContent ContentPlaceHolder в Simple.master. Выполните то же самое в элементе управления Контент, который ссылается на head ContentPlaceHolder.

Примечание

Хотя я рекомендую именовать элементы управления ContentPlaceHolder на вложенной странице master так же, как ContentPlaceHolders на странице master верхнего уровня, такая симметрия именования не требуется. Вы можете присвоить элементам управления ContentPlaceHolder на вложенной странице master любое имя. Тем не менее, мне легче запомнить, какие contentPlaceHolders соответствуют регионам страницы, если мои master страницы верхнего уровня и вложенные master страницы используют одинаковые имена.

После внесения этих дополнений SimpleNested.master декларативная разметка страницы master должна выглядеть примерно так:

<%@ Master Language="VB" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNested.master.vb" Inherits="NestedMasterPages_SimpleNested" %> 
 <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> 
 <asp:ContentPlaceHolder ID="head" runat="server"> 
 </asp:ContentPlaceHolder>
 </asp:Content> 
 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> 
 <p>Hello, from SimpleNested!</p>
 <asp:ContentPlaceHolder ID="MainContent" runat="server"> 
 </asp:ContentPlaceHolder>
 </asp:Content>

Default.aspx Удалите только что созданную страницу содержимого, а затем повторно добавьте ее, привязав SimpleNested.master к master странице. На этот раз Visual Studio добавляет два элемента управления Content в Default.aspxэлемент управления , ссылающийся на ContentPlaceHolders, который теперь определен в SimpleNested.master (см. рис. 6). Добавьте текст "Hello, from Default.aspx!" в элемент управления Контентом, который ссылается MainContentна .

На рисунке 5 показаны три задействованные здесь сущности — Simple.master, SimpleNested.masterи Default.aspx — и то, как они связаны друг с другом. Как показано на схеме, вложенная страница master реализует элементы управления Контентом для своего родительского элемента ContentPlaceHolder. Если эти регионы должны быть доступны для страницы содержимого, вложенная страница master должна добавить собственные ContentPlaceHolders в элементы управления Контент.

Макет страницы Top-Level и вложенные главные страницы диктуют макет страницы содержимого

Рис. 05. Top-Level и вложенные главные страницы диктуют макет страницы содержимого (щелкните для просмотра полноразмерного изображения)

Это поведение показывает, как страница содержимого или страница master осведомлена только о своей родительской master странице. Это поведение также определяется Designer Visual Studio. На рисунке 6 показана Designer для Default.aspx. Хотя Designer четко показывает, какие регионы можно редактировать на странице содержимого, а какие — нет, он не разбирает, какие нередактируемые регионы являются на вложенной странице master и какие регионы находятся на странице master верхнего уровня.

Страница содержимого теперь включает элементы управления содержимым для ContentPlaceHolders вложенной главной страницы

Рис. 06. Страница содержимого теперь включает элементы управления содержимым для ContentPlaceHolders вложенной главной страницы (щелкните для просмотра полноразмерного изображения)

Шаг 3. Добавление второй простой вложенной главной страницы

Преимущество вложенных страниц master более очевидно при наличии нескольких вложенных master страниц. Чтобы проиллюстрировать это преимущество, создайте в NestedMasterPages папке другую вложенную страницу master, назовите эту новую вложенную master страницу SimpleNestedAlternate.master и привяжите Simple.master ее к master странице. Добавьте элементы управления ContentPlaceHolder во вложенную страницу master два элемента управления Контент, как это было на шаге 2. Кроме того, добавьте текст "Hello, from SimpleNestedAlternate!" в элементе управления Контент, который соответствует contentPlaceHolder страницы MainContent верхнего уровня master. После внесения этих изменений декларативная разметка новой вложенной master страницы должна выглядеть примерно так:

<%@ Master Language="VB" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNestedAlternate.master.vb" Inherits="NestedMasterPages_SimpleNestedAlternate" %> 
 <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
 <asp:ContentPlaceHolder ID="head" runat="server">
 </asp:ContentPlaceHolder> </asp:Content> 
 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
 <p>Hello, from SimpleNestedAlternate!</p> 
 <asp:ContentPlaceHolder ID="MainContent" runat="server">
 </asp:ContentPlaceHolder> 
 </asp:Content>

Создайте страницу содержимого с именем Alternate.aspx в папке NestedMasterPages и привяжите SimpleNestedAlternate.master ее к вложенной странице master. Добавьте текст "Hello, from Alternate!" в элементе управления Контент, соответствующий MainContent. На рисунке 7 показан Alternate.aspx просмотр с помощью Designer Visual Studio.

Alternate.aspx привязано к SimpleNestedAlternate. главная страница master

Рис. 07. Alternate.aspx Привязывается к эталонной SimpleNestedAlternate.master странице (щелкните для просмотра полноразмерного изображения)

Сравните Designer на рис. 7 с Designer на рис. 6. Обе страницы содержимого используют один и тот же макет, определенный на странице master верхнего уровня (Simple.master), а именно заголовок "Учебник по вложенным главным страницам (простой)". Тем не менее, на родительских master страницах определено отдельное содержимое— текст "Hello, from SimpleNested!" на рис. 6 и "Hello, from SimpleNestedAlternate!" на рис. 7. Конечно, эти различия здесь тривиальны, но вы можете расширить этот пример, чтобы включить более значимые различия. Например, SimpleNested.master страница может содержать меню с параметрами, относящимися к страницам содержимого, в то время как может содержать сведения, относящиеся к страницам содержимого, которые к ней привязаны SimpleNestedAlternate.master .

Теперь представьте, что нам нужно внести изменения в макет поверх сайта. Например, предположим, что мы хотим добавить список общих ссылок на все страницы содержимого. Для этого мы обновим страницу Simple.mastermaster верхнего уровня . Любые изменения сразу же отражаются на вложенных страницах master и, соответствующих страницах содержимого.

Чтобы продемонстрировать простоту изменения макета сайта, откройте Simple.master страницу master и добавьте следующую разметку между элементами topContent и mainContent<div> :

<div id="navContent"> 
 <asp:HyperLink ID="lnkDefault" runat="server" 
 NavigateUrl="~/NestedMasterPages/Default.aspx" 
 Text="Nested Master Page Example 1" /> 
 | 
 <asp:HyperLink ID="lnkAlternate" runat="server" 
 NavigateUrl="~/NestedMasterPages/Alternate.aspx" 
 Text="Nested Master Page Example 2" /> 
</div>

При этом в начало каждой страницы добавляются две ссылки, которые привязываются к Simple.master, SimpleNested.masterили SimpleNestedAlternate.master. Эти изменения сразу же применяются ко всем вложенным страницам master и страницам их содержимого. На рисунке 8 показано Alternate.aspx при просмотре через браузер. Обратите внимание на добавление ссылок в верхней части страницы (по сравнению с рис. 7).

Изменение на главную страницу Top-Level немедленно отражаются на вложенных главных страницах и страницах их содержимого

Рис. 08. Изменение на главную страницу Top-Level немедленно отражаются на вложенных главных страницах и страницах их содержимого (щелкните для просмотра полноразмерного изображения)

Использование вложенной главной страницы для раздела администрирования

На этом этапе мы рассмотрели преимущества вложенных страниц master и увидели, как создавать и использовать их в ASP.NET приложении. Однако в примерах в шагах 1, 2 и 3 было показано создание новой страницы master верхнего уровня, новых вложенных страниц master и страниц контента. Как насчет добавления новой вложенной страницы master на веб-сайт с существующими страницами master верхнего уровня и страницами контента?

Интеграция вложенной страницы master в существующий веб-сайт и связывание ее с существующими страницами контента требует немного больше усилий, чем с нуля. В шагах 4, 5, 6 и 7 рассматриваются эти проблемы по мере расширения демонстрационного приложения и включения новой вложенной страницы master с именем AdminNested.master , которая содержит инструкции для администратора и используется ASP.NET страницами в папке~/Admin.

Интеграция вложенной страницы master в демонстрационное приложение приводит к следующим препятствиям:

  • Существующие страницы содержимого в папке ~/Admin имеют определенные ожидания от их master страницы. Для начала они ожидают наличие определенных элементов управления ContentPlaceHolder. Кроме того, ~/Admin/AddProduct.aspx страницы и ~/Admin/Products.aspx вызывают открытый RefreshRecentProductsGrid метод страницы master, задают ее GridMessageText свойство или имеют обработчик PricesDoubled события. Следовательно, наша вложенная страница master должна содержать одни и те же Элементы ContentPlaceHolders и открытые члены.
  • В предыдущем руководстве мы улучшили BasePage класс, чтобы динамически задавать Page свойство объекта MasterPageFile на основе переменной Session. Как поддерживать динамические страницы master при использовании вложенных страниц master?

Эти две проблемы будут возникать, когда мы создадим вложенную страницу master и используем ее из существующих страниц содержимого. Мы расследуем и устраняем эти проблемы по мере их возникновения.

Шаг 4. Создание вложенной главной страницы

Наша первая задача — создать вложенную страницу master, которую будут использовать страницы в разделе Администрирование. Как мы видели на шаге 2, при добавлении новой вложенной страницы master необходимо указать родительскую страницу master вложенной master страницы. Но у нас есть две страницы master верхнего уровня: Site.master и Alternate.master. Напомним, что мы создали Alternate.master в предыдущем руководстве и написали код в BasePage классе , который присваивал свойству Page объекта MasterPageFile во время выполнения значение Site.master или Alternate.master в зависимости от значения переменной MyMasterPage Session.

Как настроить вложенную страницу master таким образом, чтобы она использовала соответствующую страницу master верхнего уровня? Это можно сделать двумя способами.

  • Создайте две вложенные страницы AdminNestedSite.master master и AdminNestedAlternate.masterи привяжите их к страницам верхнего уровня master Site.master и Alternate.masterсоответственно. В BasePageзатем мы задали Page объекту MasterPageFile соответствующую вложенную страницу master.
  • Создайте одну вложенную страницу master, чтобы страницы содержимого использовали именно эту страницу master. Затем во время выполнения необходимо задать для свойства вложенной страницы MasterPageFile master соответствующую страницу master верхнего уровня во время выполнения. (Как вы уже поняли, master страницы также имеют MasterPageFile свойство.)

Давайте воспользуемся вторым вариантом. Создайте один вложенный файл master подкачки в папке ~/Admin с именем AdminNested.master. Site.master Так как и Alternate.master имеют одинаковый набор элементов управления ContentPlaceHolder, не имеет значения, к какой странице master вы привязываете их, хотя я призываю привязать их для Site.master обеспечения согласованности.

Добавьте вложенную главную страницу в папку ~/Администратор.

Рис. 09. Добавление в папку вложенной главной ~/Admin страницы. (Щелкните для просмотра полноразмерного изображения)

Так как вложенная страница master привязана к master странице с четырьмя элементами управления ContentPlaceHolder, Visual Studio добавляет четыре элемента управления Content в начальную разметку нового файла вложенной master страницы. Как и в шагах 2 и 3, добавьте элемент управления ContentPlaceHolder в каждый элемент управления Контент, присвоив ему то же имя, что и элементу управления ContentPlaceHolder верхнего уровня master страницы. Кроме того, добавьте следующую разметку в элемент управления Контент, соответствующий MainContent ContentPlaceHolder:

<div class="instructions"> 
 <b>Administration Instructions:</b>
 <br /> 
 The pages in the Administration section allow you, the Administrator, to 
 add new products and view existing products. 
</div>

Затем определите instructions класс CSS в файлах Styles.css CSS и AlternateStyles.css . Следующие правила CSS приводят к отображению элементов HTML в стиле с instructions классом светло-желтого цвета фона и черной сплошной границы:

.instructions 
{
 padding: 6px; 
 border: dashed 1px black; 
 background-color: #ffb; 
 margin-bottom: 10px; 
}

Так как эта разметка была добавлена на вложенную страницу master, она будет отображаться только на тех страницах, которые используют эту вложенную master страницу (а именно страницы в разделе Администрирование).

После добавления этих элементов на вложенную страницу master ее декларативная разметка должна выглядеть примерно так:

<%@ Master Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="AdminNested.master.vb" Inherits="Admin_AdminNested" %> 
 <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> 
 <asp:ContentPlaceHolder ID="head" runat="server"> 
 </asp:ContentPlaceHolder>
 </asp:Content> 
 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> 
 <div class="instructions">
 <b>Administration Instructions:</b>
 <br /> 
 The pages in the Administration section allow you, the Administrator, to 
 add new products and view existing products. 
 </div>
 <asp:ContentPlaceHolder ID="MainContent" runat="server"> 
 </asp:ContentPlaceHolder>
 </asp:Content> 
 <asp:Content ID="Content3" ContentPlaceHolderID="QuickLoginUI" Runat="Server"> 
 <asp:ContentPlaceHolder ID="QuickLoginUI" runat="server"> 
 </asp:ContentPlaceHolder>
 </asp:Content> 
 <asp:Content ID="Content4" ContentPlaceHolderID="LeftColumnContent" Runat="Server"> 
 <asp:ContentPlaceHolder ID="LeftColumnContent" runat="server"> 
 </asp:ContentPlaceHolder>
 </asp:Content>

Обратите внимание, что каждому элементу управления Контент имеется элемент управления ContentPlaceHolder, а свойствам элементов управления ID ContentPlaceHolder присваиваются те же значения, что и соответствующим элементам управления ContentPlaceHolder на странице master верхнего уровня. Кроме того, в ContentPlaceHolder появится разметка MainContent раздела Администрирование.

На рисунке 10 показана AdminNested.master вложенная страница master при просмотре с помощью Designer Visual Studio. Инструкции можно увидеть в желтом поле в верхней части элемента управления Содержимое MainContent .

Вложенная главная страница расширяет главную страницу Top-Level, включив инструкции для администратора.

Рис. 10. Вложенная главная страница расширяет главную страницу Top-Level, чтобы включить инструкции для администратора. (Щелкните для просмотра полноразмерного изображения)

Шаг 5. Обновление существующих страниц содержимого для использования новой вложенной главной страницы

Каждый раз, когда мы добавляем новую страницу содержимого в раздел Администрирование, необходимо привязать ее к AdminNested.master только что созданной странице master. Но как насчет существующих страниц содержимого? В настоящее время все страницы контента на сайте являются производными от BasePage класса , который программным способом задает страницу master страницы содержимого во время выполнения. Это поведение не требуется для страниц содержимого в разделе Администрирование. Вместо этого мы хотим, чтобы эти страницы содержимого всегда использовали страницу AdminNested.master . Вложенная страница master будет отвечать за выбор нужной страницы содержимого верхнего уровня во время выполнения.

Чтобы достичь этого желаемого поведения, лучше всего создать новый пользовательский базовый класс страницы с именем AdminBasePage , который расширяет BasePage класс . AdminBasePageЗатем можно переопределить SetMasterPageFile и задать Page для объекта MasterPageFile жестко заданное значение "~/Администратор/AdminNested.master". Таким образом, любая страница, производная от AdminBasePage , будет использовать AdminNested.master, тогда как для любой страницы, производной от BasePage , свойство будет MasterPageFile динамически задано как "~/Site.master" или "~/Alternate.master" на основе значения переменной MyMasterPage Session.

Начните с добавления нового файла класса в папку App_Code с именем AdminBasePage.vb. Необходимо AdminBasePage расширить BasePage , а затем переопределить SetMasterPageFile метод . В этом методе присвойте MasterPageFile значение "~/Администратор/AdminNested.master". После внесения этих изменений файл класса должен выглядеть примерно так:

Public Class AdminBasePage 
 Inherits BasePage 
 Protected Overrides Sub SetMasterPageFile() 
 Me.MasterPageFile = "~/Admin/AdminNested.master" 
 End Sub 
End Class

Теперь нам нужно, чтобы существующие страницы содержимого в разделе Администрирование были производными от AdminBasePage вместо BasePage. Перейдите к файлу класса программной части для каждой страницы содержимого в папке ~/Admin и внесите это изменение. Например, в ~/Admin/Default.aspx можно изменить объявление класса кода программной части с:

Partial Class Admin_Default 
 Inherits BasePage

В:

Partial Class Admin_Default 
 Inherits AdminBasePage

На рисунке 11 показано, как страницы master верхнего уровня (Site.master или Alternate.master), вложенные страницы master (AdminNested.master) и страницы содержимого раздела "Администрирование" связаны друг с другом.

Вложенная главная страница определяет содержимое страниц в разделе

Рис. 11. На вложенной главной странице определяется содержимое страниц в разделе администрирования (щелкните для просмотра полноразмерного изображения)

Шаг 6. Зеркальное отображение открытых методов и свойств главной страницы

Помните, что ~/Admin/AddProduct.aspx страницы и ~/Admin/Products.aspx программно взаимодействуют со страницей master: ~/Admin/AddProduct.aspx вызывает открытый RefreshRecentProductsGrid метод страницы master и задает его GridMessageText свойство; ~/Admin/Products.aspx имеет обработчик событий для PricesDoubled события. В предыдущем руководстве мы создали MustInheritBaseMasterPage класс, который определил эти открытые члены.

Страницы ~/Admin/AddProduct.aspx и ~/Admin/Products.aspx предполагают, что их master страница является производным BaseMasterPage от класса . Однако AdminNested.master в настоящее время страница расширяет System.Web.UI.MasterPage класс . В результате при посещении ~/Admin/Products.aspxInvalidCastException возникает сообщение : "Не удается привести объект типа "ASP.admin_adminnested_master" к типу BaseMasterPage".

Чтобы исправить эту проблему, необходимо, чтобы класс кода программной AdminNested.master части расширял BaseMasterPage. Обновите объявление класса кода программной части страницы для вложенных master из:

Partial Class Admin_AdminNested 
 Inherits System.Web.UI.MasterPage

В:

Partial Class Admin_AdminNested 
 Inherits BaseMasterPage

Мы еще не закончили. Необходимо переопределить элементы, помеченные как MustOverride, а именно RefreshRecentProductsGrid и GridMessageText. Эти элементы используются страницами master верхнего уровня для обновления пользовательских интерфейсов. (На самом деле, только Site.master master странице используются эти методы, хотя эти методы реализуются на обоих master страницах верхнего уровня, так как они расширяют .BaseMasterPage)

Хотя нам нужно реализовать эти члены в AdminNested.master, все эти реализации необходимо просто вызвать один и тот же член на странице master верхнего уровня, используемой вложенной страницей master. Например, когда страница содержимого в разделе Администрирование вызывает метод вложенной master страницыRefreshRecentProductsGrid, все, что нужно сделать для вложенной master страницы, это, в свою очередь, вызов Site.master метода или Alternate.masterRefreshRecentProductsGrid .

Для этого сначала добавьте следующую @MasterType директиву в начало :AdminNested.master

<%@ MasterType TypeName="BaseMasterPage" %>

Помните, что директива @MasterType добавляет строго типизированное свойство в класс кода программной части с именем Master. Затем переопределите RefreshRecentProductsGrid члены и GridMessageText и просто делегируйте вызов соответствующему Masterметоду:

Partial Class Admin_AdminNested 
 Inherits BaseMasterPage 
 Public Overrides Property GridMessageText() As String 
 Get 
 Return Master.GridMessageText 
 End Get 
 Set(ByVal value As String) 
 Master.GridMessageText = value 
 End Set 
 End Property 
 Public Overrides Sub RefreshRecentProductsGrid()
 Master.RefreshRecentProductsGrid()
 End Sub 
End Class

С помощью этого кода вы сможете просматривать и использовать страницы содержимого в разделе Администрирование. На рисунке 12 показана ~/Admin/Products.aspx страница при просмотре в браузере. Как видите, страница содержит поле Инструкции администрирования, определенное на вложенной странице master.

Страницы содержимого в разделе

Рис. 12. Страницы содержимого в разделе Администрирование содержат инструкции в верхней части каждой страницы (щелкните для просмотра полноразмерного изображения)

Шаг 7. Использование соответствующей главной страницы Top-Level во время выполнения

Хотя все страницы содержимого в разделе Администрирование полностью функциональны, все они используют одну и ту же страницу master верхнего уровня и игнорируют страницу master, выбранную пользователем в ChooseMasterPage.aspx. Это связано с тем, что в <%@ Master %> директиве для вложенной страницы master свойству MasterPageFileSite.master присвоено значение .

Чтобы использовать страницу master верхнего уровня, выбранную конечным пользователем, необходимо задать AdminNested.masterMasterPageFile для свойства значение в переменной MyMasterPage Session. Так как мы задаем свойства страниц содержимого MasterPageFile в BasePage, вы можете подумать, что мы задали бы свойство вложенной master страницы MasterPageFile в BaseMasterPage классе кода программной части или в AdminNested.masterклассе кода программной части. Однако это не сработает, так как нам нужно задать MasterPageFile свойство к концу этапа PreInit. Самый ранний момент, когда мы можем программно подключиться к жизненному циклу страницы с master страницы, — это этап Инициализация (который происходит после этапа PreInit).

Поэтому нам нужно задать свойство вложенной master страницы MasterPageFile содержимого. Единственные страницы содержимого, использующие страницу AdminNested.master master, являются производными от AdminBasePage. Поэтому мы можем поместить эту логику туда. На шаге 5 мы переопределим SetMasterPageFile метод , задав свойству объекта MasterPageFile Page значение ~/Администратор/AdminNested.master. Обновите SetMasterPageFile , чтобы также задать для свойства страницы MasterPageFile master результат, хранящийся в сеансе:

Public Class AdminBasePage 
 Inherits BasePage 
 Protected Overrides Sub SetMasterPageFile() 
 Me.MasterPageFile = "~/Admin/AdminNested.master" 
 Page.Master.MasterPageFile = MyBase.GetMasterPageFileFromSession() 
 End Sub 
End Class

МетодGetMasterPageFileFromSession, добавленный в класс в BasePage предыдущем руководстве, возвращает соответствующий master путь к файлу страницы на основе значения переменной Session.

После этого изменения выбор страницы master пользователя переносится в раздел Администрирование. На рисунке 13 показана та же страница, что и на рисунке 12, но после того, как пользователь изменил master выбор страницы на Alternate.master.

На вложенной странице администрирования используется главная страница Top-Level, выбранная пользователем

Рис. 13. На вложенной странице администрирования используется главная страница Top-Level, выбранная пользователем (щелкните для просмотра полноразмерного изображения)

Сводка

Как и при привязке страниц содержимого к master странице, можно создать вложенные master страницы, привязав дочернюю страницу master к родительской странице master. Дочерняя страница master может определять элементы управления контентом для каждого элемента управления ContentPlaceHolders своего родительского элемента. Затем он может добавить собственные элементы управления ContentPlaceHolder (а также другие разметки) в эти элементы управления Контентом. Вложенные master страницы очень полезны в крупных веб-приложениях, где все страницы имеют общий внешний вид, но некоторые разделы сайта требуют уникальных настроек.

Счастливого программирования!

Дополнительные материалы

Дополнительные сведения о темах, рассмотренных в этом руководстве, см. в следующих ресурсах:

Об авторе

Скотт Митчелл(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