Средства форматирования страниц
Управление другими элементами мастер-страницы
Рассмотрим управление элементами заполнителя мастер-страницы из страницы содержимого на примере дескриптора <h1>, определенного в заполнителе так
<h1 style="color: Green"> Мы приветствуем Вас на нашем сайте!!! </h1>
Его отображение в броузере будет следующим
- Дополните дескриптор <h1> мастер-страницы Title.master необходимыми для программного управления атрибутами
<h1 style="color: Green" runat="server" id="Header1"> Мы приветствуем Вас на нашем сайте!!! </h1>
Управлять будем из страницы SatelliteExt.aspx одним из двух способов:
- Инкапсулируем (упакуем) в мастер-странице дескриптор <h1> в отдельное свойство с именем MyHeader1 и из страницы содержимого будем обращаться к нему через это свойство
- Не трогая код мастер-страницы, найдем из страницы содержимого дескриптор <h1> по его ID и будем обращаться к нему напрямую
Первый способ
-
Двойным щелчком на свободном месте мастер-страницы в режиме Design (или вручную) создайте блок скриптов, который заполните так
<%@ Master Language="C#" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { } public string MyHeader1 { get { return Header1.InnerText; } set { Header1.InnerText = value; } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Мастер-страница Title.master</title> </head> <body> <form id="form1" runat="server"> <div style="text-align: center"> <asp:Image ID="ImageBanner" runat="server" ImageUrl="~/MasterPages/Banner.png" /> <h1 style="color: Green" runat="server" id="Header1"> Мы приветствуем Вас на нашем сайте!!! </h1> ............................................. </div> </form> </body> </html>
-
Дополните страницу содержимого SatelliteExt.aspx следующим кодом
<%@ Page Language="C#" MasterPageFile="~/MasterPages/Title.master" Title="Декларативный заголовок SatelliteExt.aspx" %> <%@ MasterType VirtualPath="~/MasterPages/Title.master" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { // Получаем ссылку на мастер-страницу Page masterPage = Master.Page; // Переопределяем строку заголовка masterPage.Header.Title = "Программный заголовок SatelliteExt.aspx"; // Управляем дескриптором h1 Master.MyHeader1 = "Это программно подмененный" + " заголовок мастер-страницы (способ 1)!"; } </script>
- Исполните страницу SatelliteExt.aspx и убедитесь, что дескриптор <h1>, относящийся к заполнителю мастер-страницы, подменяется нашим текстом
Директива @ MasterType указывает ASP.NET виртуальный путь к соответствующему файлу мастер-страницы.
Второй способ
-
Измените страницу содержимого SatelliteExt.aspx следующим образомМетод FindControl() ищет указанный элемент на мастер-странице среди элементов заданного типа, и если находит, то возвращает странице содержимого ссылку на этот элемент. Затем уже мы обращаемся к конкретным свойствам этого элемента.
<%@ Page Language="C#" MasterPageFile="~/MasterPages/Title.master" Title="Декларативный заголовок SatelliteExt.aspx" %> <%@ MasterType VirtualPath="~/MasterPages/Title.master" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { // Получаем ссылку на мастер-страницу Page masterPage = Master.Page; // Переопределяем строку заголовка masterPage.Header.Title = "Программный заголовок SatelliteExt.aspx"; // Управляем дескриптором h1 // Master.MyHeader1 = "Это программно подмененный" // + " заголовок мастер-страницы (способ 1)!"; HtmlGenericControl h1 = Master.FindControl("Header1") as HtmlGenericControl; if (h1 != null) { h1.InnerText = "Это программно подмененный" + " заголовок мастер-страницы (способ 2)!"; } } </script>
- Исполните страницу SatelliteExt.aspx и убедитесь, что дескриптор <h1>, относящийся к заполнителю мастер-страницы, подменяется нашим текстом
Второй способ более предпочтительный, поскольку мы не вмешиваемся в код спроектированной мастер-страницы, которая может быть подключена еще к чему-нибудь!
Программное переключение мастер-страниц из страницы содержимого
Иногда может возникнуть необходимость дать возможность пользователю подключать необходимые мастер-страницы. Мы уже рассматривали подобный способ, когда говорили о динамическом подключении тем. Там мы программно определяли значение атрибута Page.Theme в директиве @Page. Теперь нам нужно программно менять атрибут Page.MasterPageFile.
Здесь нужно иметь ввиду следующее:
- Страница содержимого, динамически меняющая мастер-страницу, не должна иметь ссылок на несуществующие в новой мастер-странице контейнеры ContentPlaceHolderID
- Замена мастер-страницы должна выполняться в обработчике события Page.PreInit страницы содержимого. Если это сделать в обработчиках более поздних событий, то будет сгенерировано исключение
- Все страницы содержимого, на которые имеются ссылки в текущей странице содержимого, должны иметь код подключения выбранной мастер-страницы
- Для межстраничной передачи информации о выбранной мастер-странице ее нужно где-то сохранять. Как и в случае с темами, это могут быть скрытые поля состояния вида ( VIEWSTATE ), глобальные объекты уровня сеанса или приложения
Учитывая, что наши страницы Satellite.aspx, Satellite1.aspx, Satellite2.aspx, Satellite3.aspx согласованы с Title.master, сделаем их копии и настроим под динамическую смену мастер-страниц.
- Откройте мастер-страницу Title.master и добавьте выше объекта ImageBanner (после открывающего дескриптора <div> ) элемент ContentPlaceHolder с именем ContentPlaceHolderList. Сохраните и закройте файл Title.master
- Сделайте копии соответствующих файлов и присвойте им имена Title1.master, SatelliteDynamic.aspx, SatelliteDynamic1.aspx, SatelliteDynamic2.aspx, SatelliteDynamic3.aspx
- Определите страницу SatelliteDynamic.aspx стартовой
-
Откройте мастер-страницу Title1.master и выполните в ней следующее:
- Полностью удалите контейнер скриптов <script runat="server">...</script>
- Удалите объект ImageBanner и внесите еще какие-нибудь визуально отличимые изменения
- Добавьте к гиперссылкам HyperLink еще одну с названием "Автошкола в целом"
- Заполните свойство NavigateUrl гиперссылок значениями новых страниц содержимого
- Откройте страницу содержимого SatelliteDynamic.aspx и в режиме Design создайте контейнер содержимого для шаблона ContentPlaceHolderList, выполнив на нем команду Create Custom Content контекстного меню
- Добавьте в контейнер содержимого предваряющий текст "Выберите мастер-страницу:" и элемент DropDownList с именем lstMasterPages
- Заполните раскрывающийся список lstMasterPages так
- Установите для списка lstMasterPages свойство AutoPostBack="True"
- В режиме Design двойным щелчком на тускло просвечивающемся заполнителе мастер-страницы создайте контейнер для скриптов, обработчик Page_Load() и переименуйте его в Page_Init()
- Скопируйте заготовку обработчика Page_Init() и переименуйте копию в Page_PreInit(), поскольку все они имеют одинаковую сигнатуру
- В режиме Design двойным щелчком на объекте lstMasterPages списка создайте обработчик изменения выбора опции lstMasterPages_SelectedIndexChanged()
-
Заполните обработчики так, чтобы окончательный код страницы был таким
<%@ Page Language="C#" MasterPageFile="~/MasterPages/Title.master" Title="Untitled Page" %> <script runat="server"> protected void Page_Init(object sender, EventArgs e) { if (Session["index"] != null) { // Восстанавливаем новое состояние списка lstMasterPages.SelectedIndex = (int)Session["index"]; } } protected void Page_PreInit(object sender, EventArgs e) { if (Session["Master"] != null) { // Был ранее сохраненный выбор, включить его Page.MasterPageFile = (string)Session["Master"]; } } protected void lstMasterPages_SelectedIndexChanged(object sender, EventArgs e) { // Запоминаем новый выбор пользователя Session["Master"] = lstMasterPages.SelectedValue; // Запоминаем новое состояние списка Session["index"] = lstMasterPages.SelectedIndex; // Обновляем страницу без полного цикла, // чтобы новая мастер-страница вступила в действие Server.Transfer(Request.FilePath); } </script> <asp:Content ID="Content1" runat="server" ContentPlaceHolderID="ContentPlaceHolderList"> Выберите мастер-страницу: <asp:DropDownList ID="lstMasterPages" runat="server" OnSelectedIndexChanged="lstMasterPages_SelectedIndexChanged" AutoPostBack="True"> <asp:ListItem Value="~/MasterPages/Title.master">Мастер-страница с баннером </asp:ListItem> <asp:ListItem Value="~/MasterPages/Title1.master">Мастер-страница без баннера </asp:ListItem> </asp:DropDownList> </asp:Content>
-
Откройте поочередно файлы SatelliteDynamic1.aspx, SatelliteDynamic2.aspx, SatelliteDynamic3.aspx и добавьте в каждый из них после директивы @Page такой блок скриптов
<script runat="server"> protected void Page_PreInit(object sender, EventArgs e) { if (Session["Master"] != null) { // Был ранее сохраненный выбор, включить его Page.MasterPageFile = (string)Session["Master"]; } } </script>
- Исполните начальную страницу SatelliteDynamic.aspx и убедитесь, что мы дали пользователю полнофункциональный механизм выбора мастер-страниц