Цель этой статьи состоит в том, чтобы создать гладкое выглядящее и простое в использовании меню для веб -сайта с поддержкой ASP.NET. Для этого мы будем использовать стандартную функциональность меню меню ASP.NET и улучшить внешний вид исключительно, используя листы каскадных стилей (CSS).
Для тех из вас, кто знаком с CSS, название этой статьи, несомненно, позвонит колоколу. CSS, используемые для улучшения внешнего вида и ощущения контроля меню ASP.NET, придается широко известной статье в списке, озаглавленной «Раздвижные двери CSS».
CSS, используемые для улучшения внешнего вида меню, подробно объясняется в статье в списке отдельно. Кредит, когда кредит должен. Спасибо Дугласу Боумену за то, что поставили нас с CSS. Обязательно прочитайте его статью в первую очередь, если вы не знакомы с ней.
Основное внимание в этой статье уделяется имитации такого меню в среде ASP.NET. Начнем ...
Давайте запустим Visual Studio 2008 и создадим новый проект, используя шаблон проекта веб -приложения ASP.NET. Этот шаблон автоматически добавит веб -форму по умолчанию соответствующим образом с именем «default.aspx». Откройте его в редакторе и добавьте элемент управления меню с набора инструментов, который вы можете найти на вкладке «Навигация». Если вы запустите веб -сайт сейчас, вы окажетесь на пустой странице. Чтобы меню отображало все, что сначала должно быть связано с некоторыми данными.
Самый простой способ определить данные для контроля меню для использования и позволения посетителям перемещаться по веб -сайту, - это связать их с картой сайта. Добавьте новый элемент карты сайта в проект, используя предлагаемое имя "web.sitemap". Карта сайта представляет собой XML -файл, который организует страницы сайта иерархическим образом. Дополнительным преимуществом является то, что на него автоматически ссылается управление SiteMapDataSource.
Затем добавьте несколько страниц в карту сайта, как показано в списке ниже.
Листинг 1 - 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 = " Default.aspx " title = " Home " description = " Take me back to the dasboard " />
< siteMapNode url = " Products.aspx " title = " Products " description = " Browse our catalog " />
< siteMapNode url = " Download.aspx " title = " Download " description = " Download neat stuff " />
< siteMapNode url = " Forum.aspx " title = " Forum " description = " Ask questions on our forum " />
< siteMapNode url = " Contact.aspx " title = " Contact " description = " Contact us " />
</ siteMapNode >
</ siteMap >Теперь добавьте элемент управления SiteMapDataSource на страницу и установите свойство DataSourceID управления меню на идентификатор источника данных. Также установите свойство ориентации управления меню на горизонтальное, поскольку по умолчанию по умолчанию вертикально. И последнее, но не менее важное, установите свойство ShowStartingNode в SiteMapDataSource на false. Если вы не делаете это только корневой узел отобразится, и мы не хотим включать этот базовый узел в меню. Ваш код должен теперь напоминать код, отображаемый в списке 2.
Листинг 2 - default.aspx
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
> </ asp:Menu >
< asp:SiteMapDataSource
ID =" SiteMapDataSource1 "
runat =" server "
ShowStartingNode =" False "
/>Если вы просматриваете страницу в браузере, теперь вы увидите функциональное, но скучное меню.
Рисунок 1 - Простая горизонтальная меню

Прежде чем мы сможем начать применять CSS в меню, есть еще одна проблема, которую необходимо решить в первую очередь. Если вы посмотрите на полученный HTML -код, который генерируется при запросе страницы Default.aspx, вы заметите, что элемент управления меню не генерирует наиболее гибкий HTML -код. По умолчанию он завершает каждый пункт меню в таблице. Это не поддается легко применению CSS. Было бы лучше, если бы контроль меню сгенерировал неупорядоченный список, который содержит все элементы меню.
К счастью, сгенерированный HTML может быть отрегулирован с помощью управляющих адаптеров. Адаптеры управления позволяют вам отображать HTML, который вы предпочитаете. К счастью, такие адаптеры управления легко доступны на Codeplex. Комплект для адаптеров CSS Friendly Control предоставляет предварительно созданные адаптеры управления, в том числе один для управления меню ASP.NET.
Чтобы использовать адаптеры CSS Friendly Control, следуйте этим шагам:
Необходимо использовать исходный код и скомпилировать самим сборку cssfriendly.dll, потому что нам нужно настроить некоторые из CSS, используемых адаптерами позже в этой статье.
При добавлении проекта CSSSRINGLY в ваше решение появится мастер преобразования Visual Studio. Просто выполните преобразование, все должно идти гладко. Когда преобразование завершило все, что осталось, - это добавить ссылку на проект CSSFRICYLY из проекта веб -сайта ASP.NET.
Просто запустите веб -сайт и посмотрите на сгенерированный HTML -код.
Листинг 3 - CSS Friendly HTML -код
< div class =" AspNet-Menu-Horizontal " id =" Menu1 " >
< ul class =" AspNet-Menu " >
< li class =" AspNet-Menu-Leaf AspNet-Menu-Selected " >
< a
href =" /Default.aspx "
class =" AspNet-Menu-Link AspNet-Menu-Selected "
title =" Take me back to the dasboard "
> Home </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Products.aspx "
class =" AspNet-Menu-Link "
title =" Browse our catalog "
> Products </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Download.aspx "
class =" AspNet-Menu-Link "
title =" Download neat stuff "
> Download </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Forum.aspx "
class =" AspNet-Menu-Link "
title =" Ask questions on our forum "
> Forum </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a href =" /Contact.aspx " class =" AspNet-Menu-Link " title =" Contact us "
> Contact </ a
>
</ li >
</ ul >
</ div >Теперь все смотрит вверх.
Примечание : файл CSSfriendlyAdapters.Browser позволяет использовать, какие адаптеры для управления CSS должны использоваться. Я делаю сбой комментировать все адаптеры, кроме тех, которые я хочу использовать. Таким образом, никакие другие элементы управления «адаптированы», и они будут продолжать генерировать HTML по умолчанию.
Как вы можете видеть из кода, отображаемого в списке над адаптером для управления меню, автоматически вводят необходимые классы CSS для тегов <ul> , <li> и <a> . Это спасает нас от необходимости определить их.
Также довольно часто одна страница содержит более одного управления адаптером, такого как меню. Если вы хотите отчетливый вид для каждого управления, установите CSSSelectorClass для адаптированного управления. Например, вы можете установить значение свойства CSSSelectorClass следующим образом:
Листинг 4 - свойство CSSSelectorClass
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
> </ asp:Menu > Результатом является то, что HTML -код, сгенерированный адаптированным управлением, будет содержаться в новом уровне ( <div> ).
Листинг 5 - Обертывание сгенерированного HTML -кода
< div class =" PrettyMenu " id =" Menu1 " >
<!-- Other HTML code -->
</ div >Обратите внимание, что эта собственность специфична для адаптеров для дружественных к CSS. Это пользовательский атрибут (Expando), который вы можете установить для элементов управления, поддерживаемых этой библиотекой. Вам требуется больше информации о том, как работают дружественные адаптеры, затем проконсультируйтесь по следующим ссылкам:
С помощью CSSSelectorClass, генерирующего отдельный слой ( <div> ) вокруг меню, и автоматически вводимых классов CSS на месте, мы наконец готовы начать укладку меню.
Используемый CSS является примерным к статье As Sist Apart. Как упоминалось ранее, в центре внимания этой статьи находится не на структуре CSS, а скорее на том, как применить ее к контролю меню ASP.NET, чтобы получить аккуратное выглядящее табличное меню. Завершенный результат можно увидеть на рисунке 2.
Рисунок 2 - Готовый результат

На странице загрузки вы можете найти исходный код для этой статьи. Он содержит лист стиля и необходимые изображения. Просто выполните следующие шаги, чтобы воссоздать законченный результат:
<Pages> по умолчанию. (См. Листинг 6)Листинг 6 - Web.config выдержка
< system .web>
<!-- ... -->
< pages theme = " Default " >
<!-- ... -->
</ pages >
<!-- ... -->
</ system .web>CSS, используемые в моем решении, привыкает к статье в списке отдельно, но есть некоторые изменения. В основном изменения коррелируют со структурой CSS, применяемой дружелюбными адаптерами CSS.
Чтобы применить CSS, необходимо использовать правильная структура. При стилии управление, чьи HTML регулируется дружелюбным адаптером, мне удобно использовать диаграммы, упомянутые в белой бумаге. Эти диаграммы ясно показывают, как CSS структурирована.
Вы можете найти диаграмму для контроля меню здесь.
Один вопрос, который я часто зажигал на многих форумах, - это то, как реализовать горизонтальное подраздел, которое меняется, когда пользователь выбирает другую вкладку из меню верхнего уровня. Чтобы создать это, нам сначала нужно настроить карту сайта.
Листинг 7 показывает скорректированную карту сайта.
Листинг 7 - 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 = " Default.aspx " title = " Home " description = " Take me back to the dasboard " >
< siteMapNode url = " About.aspx " title = " About us " description = " " />
< siteMapNode url = " Foo.aspx " title = " Foo " description = " " />
< siteMapNode url = " Bar.aspx " title = " Bar " description = " " />
</ siteMapNode >
<!-- ... -->
</ siteMap >Для краткости в листинге 7 отображаются только элементы подзадна (узлы) для домашнего узла. Проверьте Web.Sitemap в исходном коде для полной версии. Теперь, когда вы просматриваете веб -сайт, используя эту карту сайта, вы увидите эффект, показанный на рисунке 3.
Рисунок 3 - пункты подзадна меню

Чтобы отключить этот эффект, установите свойство MaximumDynamicDisplayLevels контроля меню на ноль, как показано в списке 8.
Листинг 8 - MaximumDynamicDisplayLevels.
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
MaximumDynamicDisplayLevels =" 0 "
> </ asp:Menu >Затем добавьте второе меню и управление SiteMapDataSource и установите их свойства, как показано в списке 9.
Листинг 9 - контроль под меню
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
MaximumDynamicDisplayLevels =" 0 "
>
</ asp:Menu >
< asp:Menu
ID =" Menu2 "
runat =" server "
DataSourceID =" SitemapDataSource2 "
Orientation =" Horizontal "
CssSelectorClass =" PrettySubMenu "
>
</ asp:Menu >
< asp:SiteMapDataSource
ID =" SiteMapDataSource1 "
runat =" server "
ShowStartingNode =" False "
/>
< asp:SiteMapDataSource
ID =" SiteMapDataSource2 "
runat =" server "
StartingNodeOffset =" 1 "
ShowStartingNode =" False "
/>Мы в основном говорим второму меню, что оно должно отображать второй уровень узлов, найденных на карте сайта, и что он не должен отображать начальный узел, который соответствует выбранной вкладке первого меню.
Кроме того, CSSSelectorClass для второго меню установлена в PrettySubmenu. CSS для этого меню приходит в первое меню. Загрузите исходный код, если хотите проверить его. Запуск веб -сайта сейчас даст вам этот резкий результат.
Рисунок 4 - Стилизированные элементы меню

Последний выпуск должен быть решен. Чтобы проиллюстрировать эту проблему, проект должен быть реорганизован.
Сначала давайте добавим главную страницу в проект под названием Site.master. Переместите код, меню и источники данных, со страницы по умолчанию. После этого вы можете безопасно удалить страницу default.aspx.
Теперь давайте добавим несколько элементов формы веб -контента в проект. Добавьте формы веб -контента, которые соответствуют элементам первого узла карты сайта и его подзму, а именно:
Обязательно выберите Site.master в качестве главной страницы для каждой из этих форм веб -контента. Другие страницы, упомянутые в Интернете.
Запустите сайт снова и перейдите на страницу Foo. Это выявит проблему.
Рисунок 5 - Проблема выбора

Поскольку мы перейдем к нижнему уровню на карте сайта, меню верхнего уровня не знает, какой пункт меню он должен отмечать как выбранные. Нам нужно будет сделать некоторое кодирование в коде главной страницы, чтобы решить это.
В листинге 10 показано необходимое кусочек кода.
Листинг 10 - Выбор правильного пункта меню верхнего уровня
namespace MenuWebApplication
{
public partial class Site : System . Web . UI . MasterPage
{
private static string ExtractBaseUrl ( string url )
{
return url . Contains ( "?" ) ? url . Remove ( url . IndexOf ( '?' ) ) : url ;
}
protected void Page_Load ( object sender , EventArgs e )
{
Menu1 . DataBind ( ) ;
// Which node in the site map is currently selected?
SiteMapNode currentNode = SiteMap . CurrentNode ;
if ( currentNode != null )
{
// Obtain the Url of the currently selected node's parent node.
string parentUrl = String . Empty ;
SiteMapNode parentNode = currentNode . ParentNode ;
if ( parentNode != null )
{
parentUrl = ExtractBaseUrl ( parentNode . Url ) ;
}
// Obtain the Url of the currently selected node.
string currentUrl = ExtractBaseUrl ( currentNode . Url ) ;
// Iterate the top level menu tier.
foreach ( MenuItem menuItem in Menu1 . Items )
{
// Compare the menu item's Url against the currently
// selected node's Url or the Url of its parent.
string menuItemUrl = ExtractBaseUrl ( menuItem . NavigateUrl ) ;
if ( ( currentUrl == menuItemUrl ) || ( parentUrl == menuItemUrl ) )
{
// If either matches then mark the top level menu item as selected.
Menu1 . Items [ Menu1 . Items . IndexOf ( menuItem ) ] . Selected = true ;
break ;
}
}
}
}
}
}Теперь вы можете выбрать любой из пунктов меню Sub Menu. Соответствующий пункт меню верхнего уровня будет выбран, чтобы дать посетителю визуальный подсказку относительно того, где он в настоящее время находится на веб -сайте.
Рисунок 6 - Исправлена проблема выбора

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