Опубликован: 13.07.2010 | Уровень: специалист | Доступ: платный
Самостоятельная работа 33:

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

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

Создание в приложении файла 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>
Листинг 33.3. Код мастер-страницы MasterPage.master

В приведенном шаблоне мы определили заголовок и таблицу, состоящую из двух строк и двух столбцов. Столбцы верхней строки мы объединили и поместили в нее элемент 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:
    1. Default.aspx
    2. Products.aspx
    3. Hardware.aspx
    4. Software.aspx
    5. Services.aspx
    6. Training.aspx
    7. Consulting.aspx
    8. 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 - всплывающие подсказки включены
Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000