Практикум прикладного программирования на C# в среде VS.NET 2005

Навигация по сайту

Показывать лекцию целиком

Упражнение 1. Навигация с использованием карты сайта

Файлы к лабораторной работе Вы можете скачать здесь.

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

  • Файл Web.sitemap с описанием структуры навигации на языке XML (по аналогии с базами данных - сами данные)
  • Элементы управления SiteMapDataSource и XmlSiteMapProvider для преобразования описания структуры навигации в объектную модель (по аналогии с базами данных - поставщик и источник данных)
  • Элементы управления TreeView, Menu и SiteMapPath, непосредственно взаимодействующие с пользователем при выполнении навигации (по аналогии с базами данных - элементы отображения и редактирования данных)
  • Рассмотрим последовательно все необходимые действия для создания полноценного средства навигации по сайту с применением карты сайта.

    Создание заготовки проекта

  • Командой меню File/New/Web Site создайте новый пустой проект с именем SiteMap
  • Создайте файл Web.config с настройкой отладки debug. Для этого
  • запустите WAT (Web Site Administration Tool) командой меню Website/ASP.NET Configuration
  • в запущенном WAT выберите вкладку Application или ссылку Application Configuration
  • выберите ссылку Configure debugging and tracing и установите флажок Enable debugging
  • закройте окно WAT
  • В панели Solution Explorer щелкните на пиктограмме Refresh (в верхней части панели), чтобы обновить дерево представления файлов проекта, и убедитесь в появлении файла конфигурации сайта Web.config
  • Определение карты сайта

    Описание структуры навигации следует начинать с создания карты сайта, которая должна находиться в единственном для приложения XML -файле со стандартным именем Web.sitemap, расположенном в корне Web-дерева. Чтобы создать заготовку этого сайта, выполните следующее

  • В панели Solution Explorer выделите корень Web-дерева сайта и через контекстное меню вызовите мастер Add New Item. Установите шаблон в значение Site Map и щелкните на кнопке Add
  • Оболочка создаст заготовку карты сайта с парным XML-дескриптором <siteMap> </siteMap> и вложенными дескрипторами узлов <siteMapNode>. Дескриптор <siteMap> поддерживается одноименным классом System.Web.SiteMap, который обеспечивает доступ к иерархическому представлению сайта для выполнения навигации. Заготовка файла Web.sitemap, созданная мастером, будет выглядеть так

    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
        <siteMapNode url="" title=""  description="">
            <siteMapNode url="" title=""  description="" />
            <siteMapNode url="" title=""  description="" />
        </siteMapNode>
    </siteMap>

    Здесь представлен один корневой узел <siteMapNode></siteMapNode> и два конечных вложенных узла.

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

  • Сайт должен начинаться с одного корневого узла
  • Все узлы карты сайта должны иметь уникальные URL
  • От этого зависит правильная работа класса-поставщика XmlSiteMapProvider, который непосредственно считывает и расшифровывает информацию из файла Web.sitemap. Для считывания информации из файла другого формата потребуется другой нестандартный поставщик (но зачем нам такие заморочки).

    Корневой узел и все последующие вложенные в него родительские (раскрывающиеся) узлы иерархического дерева карты сайта должны быть представлены парными дескрипторами <siteMapNode> ...</siteMapNode>. Листья дерева карты сайта можно представить самозакрывающимся (одиночным) дескриптором <siteMapNode>.

    Определим карту сайта так, чтобы организовать иерархию страниц сайта некоторой компании по категориям

  • Скорректируйте заготовку файла Web.sitemap, созданного нами ранее, следующим образом
  • <?xml version="1.0" encoding="utf-8" ?>
    <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
        <siteMapNode url="~/Default.aspx" title="Домой"  
              description="Корневой узел (домашняя страница)">
        <siteMapNode url="~/Products.aspx" title="Товары"  
              description="Что мы продаем">
          <siteMapNode url="~/Hardware.aspx" title="Аппаратура"  
              description="Компьютеры и комплектующие" />
          <siteMapNode url="~/Software.aspx" title="Программы"  
              description="Программное обеспечение компьютеров" />
        </siteMapNode>
        <siteMapNode url="~/Services.aspx" title="Услуги"  
              description="Наши услуги">
          <siteMapNode url="~/Training.aspx" title="Обучение"  
              description="Обучение программированию" />
          <siteMapNode url="~/Consulting.aspx" title="Консультации"  
              description="Консультации по эксплуатации" />
          <siteMapNode url="~/Support.aspx" title="Поддержка"  
              description="Помощь в сопровождении программ" />
        </siteMapNode>
      </siteMapNode>
    </siteMap>

    Декларативная привязка к карте сайта

    Создание в приложении файла Web.sitemap в корне виртуального каталога автоматически инициирует запуск поставщика XmlSiteMapProvider. Его задача заключается в извлечении данных карты сайта и заполнении этими данными экземпляра класса SiteMapDataSource, который далее можно подключать для генерации HTML-кода отображения карты сайта к таким элементам, как Menu, TreeView и SiteMapPath. Технологическая цепочка извлечения и отображения данных об иерархии страниц сайта приведена на рисунке

    Использование мастер-страниц для размещения ссылок

    Для организации механизма навигации применим мастер-страницы, чтобы все ссылки карты сайта отображались на любой исполнимой странице.

  • Через контекстное меню панели Solution Explorer добавьте к корню Web -дерева сайта папку с именем MasterPages, в которой разместим шаблон для страниц, определяемых параметром URL узлов дерева карты сайта
  • Выделите папку MasterPages и добавьте в нее файл MasterPage.master командой Website/Add New Item, сбросив флажок создания файла отделенного кода
  • Заполните мастер-страницу MasterPage.master следующим кодом
  • <%@ Master Language="C#" %>
        
    <script runat="server">
        
        protected void Page_Init(object sender, EventArgs e)
        {
            if (Session["index"] != null)
            {
                // Восстанавливаем состояние радиосписка
                RadioButtonList1.SelectedIndex = (int)Session["index"];
            }
            else
            {
                RadioButtonList1.SelectedIndex = 0;
            }
            
            SelectedIndexChanged(null, EventArgs.Empty);
        }
        
        protected void SelectedIndexChanged(object sender, EventArgs e)
        {
            if (RadioButtonList1.SelectedIndex == 0)
            {
                TreeView1.Visible = true;
                Menu1.Visible = false;
            }
            else
            {
                TreeView1.Visible = false;
                Menu1.Visible = true;
            }
        
            // Запоминаем состояние радиосписка
            Session["index"] = RadioButtonList1.SelectedIndex;
        }
    </script>
        
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="head1" runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div style="text-align: center">
                <h1 style="color: Red">
                    Карта сайта некоторой организации
                </h1>
                <table>
                    <tr>
                        <td colspan="2" style="text-align: center; background-color: Silver">
                            <!-- Элемент для мгновенного представления текущей позиции -->
                            <asp:SiteMapPath ID="SiteMapPath1" runat="server">
                                <CurrentNodeTemplate>
                                    <i><b style="color: Blue">
                                        <asp:Label ID="Label1" runat="server" Text='<%# Eval("title") %>'>
                                        </asp:Label> </b></i>
                                </CurrentNodeTemplate>
                            </asp:SiteMapPath>
                        </td>
                    </tr>
                    <tr>
                        <td style="width: 250px; vertical-align: top; background-color: Yellow">
                            <!-- Дерево управления навигацией -->
                            <asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1" 
                                SelectedNodeStyle-Font-Bold="true"
                                SelectedNodeStyle-Font-Italic="true">
                            </asp:TreeView>
                            <!-- Меню управления навигацией -->
                            <asp:Menu ID="Menu1" runat="server" DataSourceID="SiteMapDataSource1" 
                                DynamicMenuItemStyle-BackColor="Yellow"
                                DynamicHoverStyle-Font-Bold="true"
                                DynamicHoverStyle-Font-Italic="true"
                                Orientation="Horizontal">
                            </asp:Menu>
                        </td>
                        <td style="vertical-align: top; background-color: Aqua">
                            <!-- Резервирует место для страниц, подгружаемых по URL узлов -->
                            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" />
                        </td>
                    </tr>
                </table>
                <!-- Невизуальный элемент источника данных -->
                <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
                <br />
                <!-- Список радиокнопок -->
                <asp:RadioButtonList ID="RadioButtonList1" runat="server" AutoPostBack="true" 
                    BorderColor="Red" BorderStyle="Solid" OnSelectedIndexChanged="SelectedIndexChanged">
                    <asp:ListItem>Использовать TreeView</asp:ListItem>
                    <asp:ListItem>Использовать Menu</asp:ListItem>
                </asp:RadioButtonList>
            </div>
        </form>
    </body>
    </html>

    В приведенном шаблоне мы определили заголовок и таблицу, состоящую из двух строк и двух столбцов. Столбцы верхней строки мы объединили и поместили в нее элемент SiteMapPath отображения пути и текущего положения пользователя из вкладки Navigation панели Toolbox.

    В левом столбце таблицы мы разместили элементы отображения карты сайта и управления навигацией TreeView1 и Menu1 из вкладки Navigation панели Toolbox. В правом столбце мы зарезервировали место для загрузки адресуемых исполнимых страниц с содержимым, которые в соответствии с привязкой к атрибуту ContentPlaceHolderID дескриптора

    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
     ...
     </asp:Content>

    будут располагаться в зарезервированном месте.

    Вслед за таблицей (или в любом другом месте) мы разместили неотображаемый объект источника данных SiteMapDataSource1, который привязали к элементам TreeView1 и Menu1 через его свойство DataSourceID. Ниже разместили список радиокнопок, чтобы дать возможность пользователю менять элементы навигации. Свойства столбцов таблицы настроили так, чтобы содержимое размещалось с самого начала, а в верхней строке - посредине.

    В результате получится такой внешний вид мастер-страницы в режиме Design

    В блоке скриптов мы организовали механизм сохранения состояния списка между сеансами приложения, а также механизм смены элементов навигации. Как только мы один из элементов навигации скрываем, он перестает генерировать соответствующий HTML-код. В шаблоне CurrentNodeTemplate элемента SiteMapPath мы связали текстовую метку Label с атрибутом title текущего узла карты сайта, определенной в файле Web.sitemap.

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

  • В панели Solution Explorer (или на открытой мастер-странице) щелкните правой кнопкой мыши на MasterPage.master и выполните команду контекстного меню Add Content Page, чтобы создать заготовку страницы содержимого Default.aspx. Повторите это действие, чтобы в сумме создать 8 заготовок таких страниц
  • Присвойте этим страницам имена согласно XML-файлу карты сайта Web.sitemap:
  • Default.aspx
  • Products.aspx
  • Hardware.aspx
  • Software.aspx
  • Services.aspx
  • Training.aspx
  • Consulting.aspx
  • Support.aspx
  • Поскольку сама мастер-страница создавалась без файла отделенного кода, то все заготовки страниц содержимого, полученные указанным способом, не будут иметь застраничный файл отделенного кода.

  • В панели Solution Explorer переместите созданные заготовки страниц содержимого из каталога MasterPages в корень сайта
  • Отредактируйте содержимое созданных заготовок страниц следующим образом
  • Примерное наполнение страниц содержимого

    Default.aspx

    <%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" 
                           Title="Untitled Page" %>
        
    <asp:Content ID="Content1" runat="Server" 
                 ContentPlaceHolderID="ContentPlaceHolder1">
        Это содержимое начальной (домашней) страницы Default.aspx, 
        где расположен титульный лист и другие "прибамбасы"
    </asp:Content>
    Products.aspx
    <%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" 
                           Title="Untitled Page" %>
        
    <asp:Content ID="Content1" runat="Server" 
                 ContentPlaceHolderID="ContentPlaceHolder1">
        Это содержимое страницы Products.aspx, 
        где расхваливаются товары, которые мы продаем
    </asp:Content>
    Hardware.aspx
    <%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" 
                           Title="Untitled Page" %>
        
    <asp:Content ID="Content1" runat="Server" 
                 ContentPlaceHolderID="ContentPlaceHolder1">
        Это содержимое страницы Hardware.aspx, 
        где перечислены компьютеры и комплектующие,
        которыми мы торгуем (спекулируем)
    </asp:Content>
    Software.aspx
    <%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" 
                           Title="Untitled Page" %>
        
    <asp:Content ID="Content1" runat="Server" 
                 ContentPlaceHolderID="ContentPlaceHolder1">
        Это содержимое страницы Software.aspx, 
        на которой мы расхваливаем программное обеспечение,
        сворованное у других, но выдаваемое за свое
    </asp:Content>
    Services.aspx
    <%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" 
                           Title="Untitled Page" %>
        
    <asp:Content ID="Content1" runat="Server" 
                 ContentPlaceHolderID="ContentPlaceHolder1">
        Это содержимое страницы Services.aspx, 
        на которой мы хвастаемся, что все можем и
        в беде не покинем, а сами только и думаем, 
        как бы обобрать до нитки
    </asp:Content>
    Training.aspx
    <%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" 
                           Title="Untitled Page" %>
        
    <asp:Content ID="Content1" runat="Server" 
                 ContentPlaceHolderID="ContentPlaceHolder1">
        Это содержимое страницы Training.aspx, 
        на которой мы популярно объясняем для невежд,
        почему Земля квадратная
    </asp:Content>
    Consulting.aspx
    <%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" 
                           Title="Untitled Page" %>
        
    <asp:Content ID="Content1" runat="Server" 
                 ContentPlaceHolderID="ContentPlaceHolder1">
        Это содержимое страницы Consulting.aspx, 
        где мы проводим консультации с нашими клиентами
    </asp:Content>
    Support.aspx
    <%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" 
                           Title="Untitled Page" %>
        
    <asp:Content ID="Content1" runat="Server" 
                 ContentPlaceHolderID="ContentPlaceHolder1">
        Это содержимое страницы Support.aspx, 
        на которой мы оказываем поддержку в сопровождении
        программного обеспечения
    </asp:Content>
  • Запустите приложение и испытайте его функциональность
  • Результат для двух вариантов будет примерно таким

    Для сложных сайтов, разрабатываемых разными людьми, карта сайта может быть большой и весьма запутанной. В таких случаях ее можно разбить на несколько именованных файлов и ссылки на эти файлы подключать в главном файле Web.sitemap.

  • В панели Solution Explorer командой Add New Item контекстного меню для корневого узла сайта создайте по шаблону Site Map две заготовки с именами Products.sitemap и Services.sitemap
  • Перенесите из файла Web.sitemap в новые файлы соответствующие разделы с описанием товаров и услуг, а на их месте в главном файле оставьте ссылки с атрибутом siteMapFile
  • В результате карта сайта будет распределена по трем файлам:

    Web.sitemap
    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
      <siteMapNode url="~/Default.aspx" title="Домой"  
              description="Корневой узел (домашняя страница)">
        <siteMapNode siteMapFile="Products.sitemap" />
        <siteMapNode siteMapFile="Services.sitemap" />
      </siteMapNode>
    </siteMap>
    Products.sitemap
    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
      <siteMapNode url="~/Products.aspx" title="Товары"  
            description="Что мы продаем">
        <siteMapNode url="~/Hardware.aspx" title="Аппаратура"  
            description="Компьютеры и комплектующие" />
        <siteMapNode url="~/Software.aspx" title="Программы"  
            description="Программное обеспечение компьютеров" />
      </siteMapNode>
    </siteMap>
    Services.sitemap
    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
      <siteMapNode url="~/Services.aspx" title="Услуги"  
            description="Наши услуги">
        <siteMapNode url="~/Training.aspx" title="Обучение"  
            description="Обучение программированию" />
        <siteMapNode url="~/Consulting.aspx" title="Консультации"  
            description="Консультации по эксплуатации" />
        <siteMapNode url="~/Support.aspx" title="Поддержка"  
            description="Помощь в сопровождении программ" />
      </siteMapNode>
    </siteMap>

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

    Некоторые свойства класса SiteMapPath
    Свойство Описание
    ParentLevelsDisplayed Устанавливает длину отображаемой иерархической цепочки. По умолчанию равен '-1', означающий, что будут показаны все родительские узлы
    PathDirection

    Устанавливает порядок отображения узлов:

  • RootToCurrent - слева направо от корневого к текущему
  • CurrentToRoot - слева направо от текущего к корневому
  • PathSeparator Определяет разделитель между отображаемыми узлами. По умолчанию равен символу " > " (больше)
    RenderCurrentNodeAsLink При включении в значение true отображает текущий узел как гиперссылку
    ShowToolTips Отключает всплывающие подсказки над узлами иерархической цепочки, определяемые значениями атрибута description в описании узлов файла Web.sitemap. По умолчанию имеет значение true - всплывающие подсказки включены

    Программное управление картой сайта

    Узлы карты сайта имеют множество свойств, в том числе свойства Url, Title и Description. Именно эти основные свойства и создает мастер оболочки в файле Web.sitemap. Если узел имеет атрибут Url, то пользователь щелчком на нем может переходить к связанной странице. Если в каком-то узле атрибут Url опустить, то узел по-прежнему будет отображаться в иерархии дерева, но не будет действовать как гиперссылка.

    До сих пор мы рассматривали взаимодействие с картой сайта без кода. Но это взаимодействие можно осуществлять и программно. В классе SiteMap, представляющем карту в целом, основные статические свойства RootNode и CurrentNode содержат ссылки на корневой и текущий узлы карты сайта как экземпляры класса SiteMapNode. Любой другой произвольный узел, например, "Консультации", можно найти по его URL через класс карты сайта с помощью следующего кода

    SiteMapNode findNode = SiteMap.Provider.FindSiteMapNode("~/Consulting.aspx");

    Далее с помощью свойств ParentNode, ChildNodes, NextSibling и PreviousSibling экземпляров класса SiteMapNode можно получить программный доступ к соседним узлам иерархии карты сайта.

    Некоторые свойства класса SiteMapNode
    Свойство Описание
    ParentNode Содержит ссылку на родительский по отношению к текущему (найденному) узел. В корневом узле возвращается null
    ChildNodes Содержит ссылку на коллекцию дочерних узлов
    HasChildNodes Булево свойство, возвращающее true, если узел имеет дочерние узлы, иначе, false, если это лист дерева
    PreviousSibling Возвращает ссылку на предыдущий узел того же уровня (родственный узел), иначе null, если этот узел единственный. Родственными называются узлы, имеющие одного и того же родителя
    NextSibling Возвращает ссылку на следующий родственный узел, иначе null, если этот узел единственный

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

    Response.Redirect(SiteMap.CurrentNode.ParentNode.Url);

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

  • Добавьте в мастер-странице MasterPage.master к таблице сверху еще одну строку с объединенными столбцами и разместите в ней из панели Toolbox последовательно две текстовых метки Label с именами lblTitle и lblDescription. Код этого фрагмента будет таким
  • <tr>
        <td colspan="2" style="text-align: center">
            <asp:Label ID="lblTitle" runat="server" />
            : nbsp;
            <asp:Label ID="lblDescription" runat="server" />
        </td>
    </tr>
  • Добавьте в мастер-странице MasterPage.master к таблице снизу еще одну строку с объединенными столбцами и разместите в ней последовательно два элемента LinkButton с именами lnkPrevious и lnkNext. Код этого фрагмента будет таким
  • <tr>
        <td colspan="2" style="text-align: center">
            <asp:LinkButton ID="lnkPrevious" runat="server" Text="< Назад" />
            nbsp;nbsp;nbsp;
            <asp:LinkButton ID="lnkNext" runat="server" Text="Вперед >" />
        </td>
    </tr>
  • Добавьте в блок скриптов обработчик Page_Load(), содержащий следующий код
  • protected void Page_Load(object sender, EventArgs e)
        {
            // Информация о текущем узле
            lblTitle.Text = SiteMap.CurrentNode.Title;
            lblDescription.Text = SiteMap.CurrentNode.Description;
        
            // Управление кнопкой "Назад"
            if (SiteMap.CurrentNode.PreviousSibling != null)
            {
                lnkPrevious.PostBackUrl = SiteMap.CurrentNode.PreviousSibling.Url;
                lnkPrevious.Enabled = true;
            }
            else
                lnkPrevious.Enabled = false;
        
            // Управление кнопкой "Вперед"
            if (SiteMap.CurrentNode.NextSibling != null)
            {
                lnkNext.PostBackUrl = SiteMap.CurrentNode.NextSibling.Url;
                lnkNext.Enabled = true;
            }
            else
                lnkNext.Enabled = false;
        }
  • Запустите приложение и убедитесь, что появилась новая функциональность перехода на родственный узел карты сайта, реализованная нами программно
  • Интерфейс пользователя после новых изменений будет таким

    Представление пользователю элементов TreeView и Menu можно изменять декларативно с помощью опции Auto Format дополнительной локальной панели задач элемента.

  • Перейдите в режим Design редактирования страницы MasterPage.master, выделите элемент TreeView1 и щелкнув на маркере, появившемся в правой верхней части элемента, выполните команду Auto Format
  • Выберите подходящие стилевые настройки элемента из списка предложенных, например, News
  • Подобным же образом настройте элемент Menu1, выбрав, например, стиль Colorful
  • Запустите приложение и убедитесь, что теперь элементы навигации генерируют более нарядный HTML-код
  • Если после выполненных настроек стиля элементов навигации посмотреть на их дескрипторный код, то можно отметить, что оболочка существенно дополнила его уточняющими стилевыми дескрипторами.

    Упражнение 2. Навигация с использованием фреймов

    Для пользователей, броузеры которых поддерживают фреймы, организовать навигацию можно иным способом. Фреймы позволяют в одном окне броузера отобразить сразу несколько самостоятельных HTML-документов, размещенных в отдельных файлах. Именно поэтому они очень удобны для создания навигационной панели сайта.

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

    Некоторые элементы кодирования фреймов
    Элемент Описание
    <frameset> ... </frameset> Определяет число фреймов и их размеры. Он делит окно броузера или фрейм (в случае вложенных фреймов) на строки и столбцы
    rows

    Атрибут дескриптора <frameset>. Задает число строк в броузере или фрейме (в случае вложенных фреймов) для размещения фреймов, а также их высоту. Возможные варианты деления:

  • Целое число - интерпретируется как количество пикселов
  • Целое число с символом % - интерпретируется как проценты от разделяемой области
  • Символ * - интерпретируется как оставшееся пространство
  • Целое число с символом * - интерпретируется как оставшееся пространство с весом
  • Например, код <frameset rows="70, 20%, *, 2*"> ... </frameset> определяет в окне 4 строки сверху вниз: первая строка будет высотой 70 пикселов; вторая займет 20% свободной области, оставшейся от первой строки; последние две строки поделят остальное в пропорциях 1/3 и 2/3 соответственно

    cols Атрибут дескриптора <frameset>. По аналогии с атрибутом rows делит область на столбцы и определяет их размеры в порядке следования в списке слева направо
    frameborder Необязательный атрибут дескриптора <frameset>, который определяет наличие рамки в дочерних фреймах. Принимает значения "33_17" или "no"
    <frame> Дескриптор, дочерний для <frameset>, и определяющий содержимое текущего фрейма. Не имеет закрывающего дескриптора
    src Атрибут дескриптора <frame>. Определяет URL отображаемого в текущем фрейме документа
    name Атрибут дескриптора <frame>. Определяет имя фрейма для целевой загрузки в него нового документа, адресуемого щелчком пользователя в управляющем документе на ссылке с дополнительным атрибутом target. Если ссылка не содержит атрибута target, то новый документ загружается во фрейм, где была расположена ссылка. Если все ссылки на управляющей странице должны выводить адресуемые документы в одном и том же фрейме, то вместо добавления в каждую ссылку атрибута target с одинаковым значением можно добавить единственный дескриптор <base target=" Имя_фрейма "> в раздел <head> страницы
    scrolling

    Атрибут дескриптора <frame>. Управляет видимостью полос прокрутки. Может иметь следующие значения:

  • scrolling="auto" - автоматическое появление полос прокрутки, если содержимое документа не помещается в фрейме. При отсутствии атрибута это режим по умолчанию
  • scrolling="33_17" - полосы прокрутки присутствуют постоянно
  • scrolling="no" - полосы прокрутки не появляются даже при необходимости
  • noresize Атрибут дескриптора <frame>. Наличие этого атрибута запрещает пользователю изменение размеров фрейма посредством интерактивного перетаскивания границ
    <noframes> ... </noframes> Дескриптор, не имеющий атрибутов. Он включает в себя контейнер <body>...</body>, внутри которого может содержаться альтернативный текст или гиперссылки на случай, если броузер пользователя не поддерживает фреймы. Для броузеров, поддерживающих фреймы, содержимое этого дескриптора не отображается

    Проиллюстрируем некоторые возможности работы с фреймами.

  • Вызовите для корневого узла проекта контекстное меню и командой Add New Item добавьте к проекту (шаблон HTML Page ) 5 HTML-страниц содержимого с именами
  • Doc1.htm
  • Doc2.htm
  • Doc3.htm
  • Doc4.htm
  • Doc5.htm
  • Добавьте внутрь каждого документа соответствующий заголовок с именем страницы, например, для первой страницы разметка будет такой
  • <h3 align="center">Страница 1</h3>
  • Создайте пассивную (шаблон HTML Page ) управляющую HTML-страницу с именем Frameset1.htm и наполните ее следующей разметкой
  • <html>
    <head>
    <title>Untitled Document</title>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
    </head>
      
    <frameset rows="70%,*">
      <frameset cols="*,*,*">
        <frame src="Doc1.htm" name="Frame1" scrolling="no" noresize>
      <frame src="Doc2.htm" name="Frame2" scrolling="auto">
      <frame src="Doc3.htm" name="Frame3" scrolling="auto">
      </frameset>
      <frameset cols="*,*">
        <frame src="Doc4.htm" name="Frame1" scrolling="no" noresize>
      <frame src="Doc5.htm" name="Frame2" scrolling="auto">
      </frameset>
    </frameset>
    <noframes>
    <body>
    </body>
    </noframes>
    </html>
  • Выполните страницу Frameset1.htm, должен получиться такой результат
  • Создайте пассивную (шаблон HTML Page ) управляющую HTML-страницу с именем Frameset2.htm и наполните ее следующей разметкой
  • <html>
    <head>
    <title>Untitled Document</title>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
    </head>
      
    <frameset cols="55%,*">
      <frameset rows="*,*,*">
        <frame src="Doc1.htm" name="Frame1" scrolling="no" noresize>
      <frame src="Doc2.htm" name="Frame2" scrolling="auto">
      <frame src="Doc3.htm" name="Frame3" scrolling="auto">
      </frameset>
      <frameset rows="*,*">
        <frame src="Doc4.htm" name="Frame1" scrolling="no" noresize>
      <frame src="Doc5.htm" name="Frame2" scrolling="auto">
      </frameset>
    </frameset>
    <noframes>
    <body>
    </body>
    </noframes>
    </html>
  • Выполните страницу Frameset2.htm, должен получиться такой результат
  • Рассмотрим возможность использования фреймов в создании навигационной панели сайта для случая неактивной HTML-страницы.

  • Создайте пассивную страницу с именем Navigate.htm, содержащую ссылки на страницы содержимого ( Doc1.htm, Doc2.htm, Doc3.htm, Doc4.htm ), и заполните ее следующим кодом
  • <html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <title>Untitled Page</title>
    </head>
    <body>
        <h1 align="center">
            Навигационная панель</h1>
        <table>
            <tr>
                <th>
                    <a href="Doc1.htm" target="DocView">Документ 1 </a>
                </th>
                <th>
                    <a href="Doc2.htm" target="DocView">Документ 2 </a>
                </th>
                <th>
                    <a href="Doc3.htm" target="DocView">Документ 3 </a>
                </th>
                <th>
                    <a href="Doc4.htm" target="DocView">Документ 4 </a>
                </th>
            </tr>
        </table>
    </body>
    </html>
  • Создайте в корне виртуального каталога новую управляющую HTML-страницу с именем FramesControl.htm для размещения фреймов, назначьте ее стартовой и заполните следующим кодом
  • <html>
    <head>
        <title>Untitled Document</title>
        <meta content="text/html; charset=windows-1251" http-equiv="Content-Type">
    </head>
        
    <frameset rows="130,*">
        <frame name="Frame1" scrolling="no" src="Navigate.htm">
        <frame name="DocView" scrolling="auto" src="Doc1.htm">
    </frameset>
    </html>
  • Запустите страницу и получите следующий результат
  • Удалите в документе Navigate.htm в дескрипторах гиперссылок атрибуты target, а в заголовочную часть <head></head> этой же страницы Navigate.htm добавьте общий целевой дескриптор <base target="DocView">. Исполните страницу и убедитесь, что навигация работает без изменений
  • На примерах статических страниц мы познакомились с фреймами. Настала пора использовать их в совокупности с картой сайта. Мы не будем сильно усложнять задачу и готовить для ссылок новые страницы. Воспользуемся готовыми страницами, которые ранее определили в файле Web.sitemap. Результат будет немного неказистым, но вполне проиллюстрирует использование фреймов.

  • Добавьте в корень приложения активную страницу с именем FramesPage.aspx без файла отделенного кода, в которой будут расположены фреймы, назначьте ее стартовой и заполните следующим кодом
  • <%@ Page Language="C#" %>
        
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
        <frameset rows="70, *">
            <frame src="TitlePage.aspx" />
            <frameset cols="30%, *">
                <frame src="MenuPage.aspx" />
                <frame name="MainFrame" src="Default.aspx">
            </frameset>
        </frameset>
        <noframes>
            <body>
                <h1>Это управляющая страница-шаблон фреймов</h1>
            </body>
        </noframes>
    </html>

    Мы создали шаблон фреймов из двух строк. Верхняя строка имеет высоту 70 пикселов, а оставшаяся часть занята нижней строкой, поделенной на два столбца. Причем первый столбец займет 30% ширины окна броузера. Обратите внимание на структуру HTML-дескрипторов: дескриптор <body> присутствует только в альтернативном блоке для броузеров, не поддерживающих фреймы. Мы удалили из страницы код дескрипторов <form> и <div>, автоматически сгенерированный мастером. Страница с фреймами не требует обработки на сервере и ей бы больше подошло расширение .htm, но не будем мелочиться и оставим все как есть.

    В первый фрейм, ассоциируемый с верхней строкой, будет загружена страница TitlePage.aspx с простым текстом заголовка. Во второй фрейм поместим страницу MenuPage.aspx, в которой будет располагаться элемент TreeView, связанный с файлом Web.sitemap карты сайта. В третий, именованный фрейм, изначально будет загружена готовая домашняя страница, а затем будут подгружаться другие готовые страницы, выбираемые пользователем щелчком на узлах карты сайта.

  • Создайте новую страницу без файла отделенного кода с именем TitlePage.aspx и заполните ее следующим кодом
  • <%@ Page Language="C#" %>
        
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div style="text-align:center">
            <h2>Это заголовок панели навигации</h2>
        </div>
        </form>
    </body>
    </html>
  • Создайте новую страницу без файла отделенного кода с именем MenuPage.aspx и заполните ее следующим кодом
  • <%@ Page Language="C#" %>
        
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:TreeView ID="TreeView1" runat="server" 
                          DataSourceID="SiteMapDataSource1" 
                          SelectedNodeStyle-Font-Bold="true"
                          SelectedNodeStyle-Font-Italic="true" 
                          Target="MainFrame" />
            <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
        </div>
        </form>
    </body>
    </html>

    Обратите внимание на атрибут Target="MainFrame" элемента TreeView, который устанавливает для всех ссылок узлов дерева один и тот же именованный фрейм страницы FramesPage.aspx, где будет размещаться подгружаемое содержимое страниц.

  • Запустите управляющую страницу FramesPage.aspx и протестируйте навигацию с использованием фреймов
  • Результат внешне будет примерно таким

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

    Обратите внимание, что при смене содержимого третьего фрейма содержимое строки адреса всегда указывает на управляющую страницу FramesPage.aspx. Это один из недостатков механизма фреймов, способный ввести пользователя в заблуждение. Есть и другие недостатки. В связи с этим, технологию фреймов рекомендуют использовать только тогда, когда она действительно необходима. Альтернативный прием навигации с использованием мастер-страниц является более современным, хотя и генерирует больший объем пересылаемого HTML-кода.

    Вернуться к учебному плану