Глава 8. Использование Master Pages в Microsoft ASP.NET
Master Pages (мастер-страницы) - технология Microsoft, впервые появившаяся в ASP.NET 2.0. Эта технология позволяет создать предопределенную компоновку страниц (например, заголовок (шапку), меню, поля для отображения информации, счетчики ...) и многократно применять ее к разным страницам приложения, наполняя элементы компоновки тем содержимым, которого требует контент страницы. Параграф 1. Методика создания и использования Master PagesРеализацией технологии мастер страниц являются два новых типа страниц: мастер страница и страница содержимого. Мастер страница - это шаблон страницы с некоторым начальным фиксированным содержанием. Она может включать любую комбинацию HTML элементов и кода, а также модифицируемые области - заполнители содержимого. Страница содержимого - страница, ссылающаяся на одну мастер страницу и получающая ее компоновку и заполнители. Кроме того, страница содержимого может добавлять данные в любой заполнитель. Создадим обычным образом решение сайта (File/New/WebSite), после чего удалим из директивы "Page" все, кроме самой директивы и параметра "Language" (можно, при желании, удалить и файл Default.aspx.cs, если основная страница будет отображать только то, что ей предоставят мастер-страница и страницы контента): <%@ Page Language="C#">
Добавим мастер-страницу к решению, для чего, в контекстном меню Solutation Explorer узла решения выбираем пункт "Add New Item" (Рис.1). Задаем "Templates" - "Master Page", определяем "Name" - имя мастер-страницы, задаем "Language", ставим галочку в чекбоксе "Place code in separate file" и нажимаем кнопку ADD. В Solutation Explorer появился узел, состоящий из двух файлов - MasterPage.master и MasterPage.master.cs (Рис.1). Это и есть наша мастер страница.
Рис.1 Добавление мастер страницы к решению Мастер-страница может содержать HTML код страницы и может содержать любые контролы, сценарии и т.п., то есть все, что может содержать любая Web страница. Кроме того, мастер-страница (и только она и страницы, для которых она является старшей) может содержать (или не содержать) контролы ContentPlaceHolder. Этот элемент определяет область, которая может быть переопределена страницей, вызываемой из мастер-страницы. Рассмотрим содержимое файлов шаблона мастер страницы: Код в файле MasterPage.master имеет директиву "Master" ( вместо директивы "Page") - в остальном, он мало отличаются от кода обычной Web страницы. Новым может быть лишь появление контрола "ContentPlaceHolder" - это элемент определяет область, которая может быть переопределена конкретной страницей содержимого. <%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %> <!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 runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> </asp:contentplaceholder> </div> </form> </body> </html> Прикрепленный код в MasterPage.master.cs, говорит о том, что класс MasterPage является наследником класса System.Web.UI.MasterPage. В нем мы можем выполнять любые действия на стороне сервера, как и для обычной страницы. public partial class MasterPage : System.Web.UI.MasterPage { protected void Page_Load(object sender, EventArgs e) { } } Осталось добавить нашу мастер-страницу к файлу решения, для чего, в файле Default.aspx добавляем параметр MasterPageFile="~/MasterPage.master": <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" %> Обратим внимание, что значение параметра MasterPageFile начинается с ~/. Это означает, что мастер страница находится не в предопределенной папке MasterPages, а в корневой директории решения (хотя, можно и создать такую папку). Причина отсутствия тэгов <html>, <head>, <title>, <body> - они уже есть в мастер-странице и ни в одной другой странице решения быть не могут. Мастер страницу можно добавлять в решение и через включение объявления в web.config (<pages masterPageFile="MasterPage.master" />), но, в силу ряда недостатков и ограничений, этот путь не рекомендован разработчиками. Если выполнить решение на данном этапе, то в браузере отобразится пустая страница. Для того, чтобы страница не была пустой, наполним мастер страницу некоторым содержанием. Добавим страницы "main" и "warehouse" к решению, для чего, в контекстном меню Solutation Explorer узла решения выбираем пункт "Add New Item". Задаем Templates - Web Form, определяем "Name" (имя "main" и "warehouse" соответственно), определяем "Language" - "VisualC#", ставим галочку в чекбоксе "Place code in separate file" и в чекбоксе "Select Master Page", нажимаем кнопку ADD. После выбора MasterPage.master (он пока у нас один) в окне Select a Master Page в Solutation Explorer появятся узлы, состоящие из двух файлов с расширениями, как и у обычной страницы (.aspx, aspx.cs). Далее сформируем HTML код мастер страницы (рекомендуется просто перенести следующий код в "master.aspx" файл и посмотреть разметку в дизайнере формы): <%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %> <!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 runat="server"> <title>Домашняя страничка</title> <asp:ContentPlaceHolder id="head" runat="server"> </asp:ContentPlaceHolder> </head> <body> <form id="form1" runat="server"> <table border="1" width="50%"> <tr><th colspan="2" style="color:#800000">Trade firm OOO "Horns and hoofs"</th></tr> <tr> <td id="menu"> <asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="~/main.aspx">О нашей фирме</asp:LinkButton> <br /> <asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl="~/warehouse.aspx">Что еа складе</asp:LinkButton> </td> <td id="main"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> </asp:contentplaceholder> </td> </tr> <tr> <td colspan="2" style="text-align:center"> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> </td> </tr> </table> </form> </body> </html> Здесь мы ввели в качестве элемента разметки таблицу, хотя можно использовать и другие тэги, например, тэг "div". Файлы "main.aspx" и "warehouse.aspx" - это страницы, которые должны переопределять содержимое contentPlaceHolder1. Они имеют расширение ".aspx", как и обычные страницы. В тоже время, если файлы ".aspx.cs" ничем не отличаются от обычных файлов прикрепленного кода, то файлы ".aspx" имеют одну особенность - элементы "asp:Content" (для файла main.aspx): <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="main.aspx.cs" Inherits="main" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> </asp:Content> Все, что будет помещено внутри тэга "asp:Content" с ID="Content2" при вызове страниц "main.aspx" и "warehouseaspx" будет включено (поместится, заменит) области мастер страницы в элементах управления "ContentPlaceHolder". Ясно, что "asp:Content" c ID="Content1" предназначен для включения в мастер страницу элементов тэга "Head" (например, таблиц стилей). Это означает, что все, что мы хотим включить в мастер-страницу должно находиться в страницах содержимого в пределах элементов управления Content c ID="Content2". Внутри же их, мы можем помещать все, что допустимо в обычных страницах, например контролы "Label", "TextBox", "Button"..., создавать обработчики событий элементов: <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="main.aspx.cs" Inherits="main" Title="О нашей фирме" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> <div style ="text-align:center"> <asp:Label ID="Label1" runat="server" Text="Руководитель фирмы:"></asp:Label> <br/> <asp:TextBox ID="TextBox1" runat="server" Width="233px"></asp:TextBox> <br/> <asp:Button ID="Button1" runat="server" Text="Узнай кто!" onclick="Button1_Click" /> </div> </asp:Content> В дизайнере формы мастер страница и страница "main.aspx" выглядят, как показано на Рис.2.
Рис.2 Мастер страница и страница содержания "main.aspx" Как видно из рисунка, уже на этапе разработки формы страницы содержания включаются в мастер-страницу и составляет с ней как бы одно целое. Иначе (в нашем примере), cодержимое "суммарной" страницы будет меняться в зависимости от вызова и контента вызываемых по гиперссылкам страниц - "main.aspx" или "warehouse.aspx". И, кроме того, можно использовать код и в мастер-странице, например: public partial class MasterPage : System.Web.UI.MasterPage { protected void Page_Load(object sender, EventArgs e) { Label1.ForeColor = Color.Red; Label1.Text = "Наша фирма лучшая в мире!"; } } Добавления серверного кода в страницах содержимого выполняется обычным образом: public partial class main : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { TextBox1.Text = "Нет, это не О.Бендер!"; } } Для кода страницы "warehouse.aspx.cs" ограничимся просто выводом текста: <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="warehouse.aspx.cs" Inherits="warehouse" Title="РЎРєР>Р°Р_" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> <div style="text-align:center" > <asp:TextBox ID="TextBox1" runat="server" Text="Рогов: 2, Копыт: 4." > </asp:TextBox> </div> </asp:Content> Теперь, при старте, будет выведен текст "Наша фирма лучшая в мире!" и, далее, при выборе ссылок, получим результат, показанный на Рис.3. Обратим внимание, что основная страница наследует не только содержимое контентов, но и заглавие ("Title") страницы.
Рис.3. Выполнение решения сайта Параграф 2. Вложенные мастер страницыWeb сайт может содержать множество мастер-страниц и есть возможность вкладывать одни мастер-страницы в другие. Покажем множественное наследование мастер-страниц, для чего, несколько изменим решение:
В "MasterPage2.master,cs" запишем код обработчика нажатия кнопки: public partial class MasterPage2 : System.Web.UI.MasterPage { protected void Button1_Click(object sender, EventArgs e) { Label1.ForeColor = Color.Red; Label1.Text = "Сдавайте свои рога и копыта, господа!"; } ..... } Результат:
Рис.4. Использование вложенных мастер-страниц Красным на Рис.4. обозначено то, для чего собственно и используется вложение мастеров. Вложение позволяет выполнить некоторую распределенную последовательности действий по формированию содержимого страницы. Причем, каждое промежуточное звено может быть многократно использовано в различных их сочетаниях. Далее, результат выполнения решения будет полностью аналогичен предыдущему примеру (Рис.3.). Параграф 3. Логотипы в Master PagesДобавим рисунок в решение, для чего в контекстном меню Solutation Explorer узла решения выбираем пункт "Add Existing Item", выберем рисунок, помещенный в директорию решения. Вместо надписи "Trade firm OOO 'Horns and hoofs'" внесем ссылку на рисунок, как показано ниже (рекомендуется просто перенести следующий код в "master.aspx" файл и посмотреть разметку в дизайнере формы - Рис.5.): <%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %> <!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 runat="server"> <title>Домашняя страничка</title> <asp:ContentPlaceHolder id="head" runat="server"> </asp:ContentPlaceHolder> </head> <body> <form id="form1" runat="server"> <table border="1" width="50%"> <tr><th colspan="2" style="color:#800000"> <img src="a01.gif" alt="a01.gif" /> </th></tr> <tr> <td id="menu"> <asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="~/main.aspx">О нашей фирме</asp:LinkButton> <br /> <asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl="~/warehouse.aspx">Что еа складе</asp:LinkButton> </td> <td id="main"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> </asp:contentplaceholder> </td> </tr> <tr> <td colspan="2" style="text-align:center"> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> </td> </tr> </table> </form> </body> </html>
Рис.5. Решение с логотипом Результат - на всех страницах сайта будет присутствовать наш рисунок (Рис.6.):
Рис.6. Использование логотипов в Master Pages Если используется HTML тэг "img" (ровно, как и тэги "a"), то при развертывании приложения придется использовать полный относительный путь к рисунку (включая доменное имя), поэтому рекомендуется использовать преобразование элемента к серверному (runat="server"). В этом случае, сервер преобразует элемент к серверному "HtmlImage" и, поскольку этот объект создается после объекта "Page" (при создании мастер страницы), то Asp.Net будет интерпретировать все пути относительно мастер страницы. <img src="MasterPages/a01.gif" alt="a01.gif" runat="server"/> //Можно и так <img src="~/MasterPages/a01.gif" alt="a01.gif" runat="server"/> Параграф 4. Изменение и добавление контентовЕсли мы удалим элемент "Conten" со страницы содержимого, например из файла "main.aspx", то, в силу наличия в директиве "Page" свойства MasterPageFile="~/MasterPage.master", "ContentPlaceHolder1" будет отображен в дизайнере для страницы "main.aspx" (в виде серого квадратика), но без содержимого. Для добавления "Content", кликнем мышкой на треугольничке в правом верхнем углу элемента "ContentPlaceHolder1" и в контекстном меню (левый клик - появляется как многострочное, или правый клик - двух строчное) выбираем пункт "Create Custom Content". Элемент "Content" будет добавлен к странице (Рис.7.). <asp:Content ID="Content1" runat="server" contentplaceholderid="ContentPlaceHolder1"> </asp:Content> Если потребуется удалить контент, то необходимо выбрать пункт "Default to Mastr's Content".
Рис.7. Добавление и удаление элементов Content Параграф 5. Значение контента по умолчаниюИзначально "ContentPlaceHolder" мастер страницы пуст: <td id="main"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> </asp:contentplaceholder> </td> Уберем со страницы "warehouse.aspx", а на мастер странице в "ContentPlaceHolder1" добавим контрол "TextBox": <td id="main"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> <asp:TextBox ID="TextBox1" Text="Рогов: нет. Копыт: нет." runat="server"></asp:TextBox> </asp:contentplaceholder> </td> Выполним решение и убедимся, что "TextBox" и его содержимое со страницы мастер окажутся встроенными в страницу "warehouse.aspx" (другие страницы ведут себя, как и ранее). Таким образом, при неопределенном контенте страниц содержимого "ContentPlaceHolder" страницы заполняется содержимым по умолчанию из "ContentPlaceHolder" мастер-страницы (Рис.8.).
Рис.8. Контент по умолчанию Заметим, что контент по умолчанию может быть только полностью заменен и не может использоваться совместно с контентом страниц содержимого. Параграф 6. Динамическое задание мастер страницыAsp.Net загружает мастер-страницу сразу после генерации события "PreInit". Таким образом, для того, чтобы иметь возможность изменять мастер страницу программно, необходимо выполнять это в событии "Page_PreInit". Задание выполняется просто. В предыдущем примере можно убрать в файле "Default.aspx" в директиве "Page" атрибут "MasterPageFile" и поместить его в качестве кода в обработчик события "PreInit". Мастер-страницей в обработчике события "PreInit" зададим "MasterPage2.aspx". Выполнив решение, мы получим результат тот же, что мы видели на Рис.4. Даже если не будем убирать связь с другой мастер страницей в директиве "Page", то результат не изменится. <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" %> <script runat="server"> protected void Page_PreInit(object sender, EventArgs e) { MasterPageFile = "~/MasterPage2.master"; } </script> Молчанов Владислав 21.3.2006г.
Еcли Вы пришли с поискового сервера - посетите мою главную страничкуНа главной странице Вы найдете программы комплекса Veles - программы для автолюбителей,
программу NumberPhoto, созданную для работы с фото, сделанными цифровым фотоаппаратом,
программу Локальный Web сайт - предназначенную для просмотра и прослушивания
файлов большинства графических и звуковых форматов в Web Browser,
программу Bricks - игрушку для детей и взрослых, программу записную книжку,
программу TellMe - говорящий Русско-Английский разговорник - программу для тех, кто собирается
погостить за бугром или повысить свои знания в английском, теоретический материал
по программированию в среде Borland C++ builder, C# (Windows приложения и ASP.Net Web сайты).
|