Опубликован: 07.05.2010 | Доступ: свободный | Студентов: 1678 / 62 | Оценка: 4.56 / 4.06 | Длительность: 34:11:00
Лекция 9:

Средства форматирования страниц

Управление другими элементами мастер-страницы

Рассмотрим управление элементами заполнителя мастер-страницы из страницы содержимого на примере дескриптора <h1>, определенного в заполнителе так

<h1 style="color: Green">
    Мы приветствуем Вас на нашем сайте!!!
</h1>

Его отображение в броузере будет следующим


  • Дополните дескриптор <h1> мастер-страницы Title.master необходимыми для программного управления атрибутами
<h1 style="color: Green" runat="server" id="Header1">
    Мы приветствуем Вас на нашем сайте!!!
</h1>

Управлять будем из страницы SatelliteExt.aspx одним из двух способов:

  1. Инкапсулируем (упакуем) в мастер-странице дескриптор <h1> в отдельное свойство с именем MyHeader1 и из страницы содержимого будем обращаться к нему через это свойство
  2. Не трогая код мастер-страницы, найдем из страницы содержимого дескриптор <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 следующим образом
    <%@ 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>
    Метод FindControl() ищет указанный элемент на мастер-странице среди элементов заданного типа, и если находит, то возвращает странице содержимого ссылку на этот элемент. Затем уже мы обращаемся к конкретным свойствам этого элемента.
  • Исполните страницу SatelliteExt.aspx и убедитесь, что дескриптор <h1>, относящийся к заполнителю мастер-страницы, подменяется нашим текстом

Второй способ более предпочтительный, поскольку мы не вмешиваемся в код спроектированной мастер-страницы, которая может быть подключена еще к чему-нибудь!

Программное переключение мастер-страниц из страницы содержимого

Иногда может возникнуть необходимость дать возможность пользователю подключать необходимые мастер-страницы. Мы уже рассматривали подобный способ, когда говорили о динамическом подключении тем. Там мы программно определяли значение атрибута Page.Theme в директиве @Page. Теперь нам нужно программно менять атрибут Page.MasterPageFile.

Здесь нужно иметь ввиду следующее:

  1. Страница содержимого, динамически меняющая мастер-страницу, не должна иметь ссылок на несуществующие в новой мастер-странице контейнеры ContentPlaceHolderID
  2. Замена мастер-страницы должна выполняться в обработчике события Page.PreInit страницы содержимого. Если это сделать в обработчиках более поздних событий, то будет сгенерировано исключение
  3. Все страницы содержимого, на которые имеются ссылки в текущей странице содержимого, должны иметь код подключения выбранной мастер-страницы
  4. Для межстраничной передачи информации о выбранной мастер-странице ее нужно где-то сохранять. Как и в случае с темами, это могут быть скрытые поля состояния вида ( 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 так
    Text Value
    Items[0] Мастер-страница с баннером ~/MasterPages/Title.master
    Items[1] Мастер-страница без баннера ~/MasterPages/Title1.master
  • Установите для списка 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 и убедитесь, что мы дали пользователю полнофункциональный механизм выбора мастер-страниц