O objetivo deste artigo é criar um menu com aparência liso e fácil de usar para um site habilitado para ASP.NET. Para conseguir isso, usaremos a funcionalidade padrão do controle da web do menu ASP.NET e aprimoramos a aparência puramente usando folhas de estilo em cascata (CSS).
Para aqueles que estão familiarizados com o CSS, o título deste artigo certamente tocará um sino. O CSS usado para aprimorar a aparência do controle do menu ASP.NET é descrito em um artigo amplamente conhecido em uma lista separada, intitulada "Portas de deslizamento de CSS".
O CSS usado para melhorar a aparência do menu é completamente explicado no artigo em uma lista à parte. Crédito quando o crédito é devido. Obrigado Douglas Bowman por nos fornecer o CSS. Certifique -se de ler o artigo dele primeiro se você não estiver familiarizado com ele.
O foco deste artigo é como simular esse menu em um ambiente ASP.NET. Vamos começar ...
Vamos iniciar o Visual Studio 2008 e criar um novo projeto usando o modelo de projeto de aplicativo da Web ASP.NET. Este modelo adicionará automaticamente um formulário da Web padrão de maneira adequadamente chamada "default.aspx". Abra -o no editor e adicione o controle de menu da caixa de ferramentas que você pode encontrar na guia Navegação. Se você executar o site agora, acabará olhando para uma página em branco. Para que o menu exiba qualquer coisa que primeiro deve estar vinculado a alguns dados.
A maneira mais fácil de definir dados para o controle de menu usar e permitir que os visitantes naveguem pelo site é vinculá -los a um mapa do site. Adicione um novo item do mapa do site ao projeto usando o nome proposto de "web.sitemap". O mapa do site é um arquivo XML que organiza as páginas do site de maneira hierárquica. Uma vantagem adicional é que ele é referenciado automaticamente pelo controle SitemApDataSource.
Em seguida, adicione algumas páginas ao sitemap, conforme exibido na listagem abaixo.
Listagem 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 >Agora adicione um controle SitemApDataSource na página e defina a propriedade DataSourceId do controle de menu no ID da fonte de dados. Defina também a propriedade de orientação do controle de menu como horizontal, pois padrão é vertical. Por último, mas não menos importante, defina a propriedade ShowStartingNode da SitemApDataSource como falsa. Se você não fizer isso, apenas o nó raiz será exibido e não queremos incluir este nó base no menu. Seu código agora deve se parecer com o código exibido na Listagem 2.
Listagem 2 - Default.aspx
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
> </ asp:Menu >
< asp:SiteMapDataSource
ID =" SiteMapDataSource1 "
runat =" server "
ShowStartingNode =" False "
/>Se você visualizar a página em um navegador agora, verá um menu funcional, mas chato.
Figura 1 - Menu horizontal simples

Antes que possamos começar a aplicar o CSS no menu, há outro problema que precisa ser abordado primeiro. Se você dar uma olhada no código HTML resultante que é gerado ao solicitar a página padrão.aspx, você notará que o controle de menu não gera o código HTML mais flexível. Por padrão, ele envolve cada item de menu em uma tabela. Isso não se presta para aplicar facilmente CSS. Seria melhor se o controle de menu gerasse uma lista não -orderadora que contém todos os itens do menu.
Felizmente, o HTML gerado pode ser ajustado usando adaptadores de controle. Os adaptadores de controle permitem que você renderize o HTML que você preferir. Felizmente, esses adaptadores de controle estão prontamente disponíveis no CodePlex. O Kit Adaptadores de Controle Friendly CSS fornece adaptadores de controle pré-criados, incluindo um para o controle do menu ASP.NET.
Para usar os adaptadores de controle amigável do CSS, siga estas etapas:
É necessário usar o código -fonte e compilar o CSSFriendly.
Ao adicionar o Projeto CSS Friendly à sua solução, o assistente de conversão do Visual Studio será exibido. Basta executar a conversão, tudo deve correr bem. Quando a conversão concluir tudo o que resta é adicionar uma referência ao projeto do CSSS Friendly no projeto do site do ASP.NET.
Basta executar o site e dar uma olhada no código HTML gerado agora.
Listagem 3 - Código HTML amigável do CSS
< 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 >As coisas estão melhorando agora.
Observação : o arquivo CSSFriendlyAdapters.Browser permite especificar quais adaptadores de controle amigável do CSS devem ser usados. Faço um hábito de comentar todos os adaptadores, exceto os que quero usar. Dessa forma, nenhum outro controle é "adaptado" e eles continuarão gerando o HTML padrão.
Como você pode ver no código exibido na listagem acima do adaptador para o controle de menu, injeta automaticamente as classes CSS necessárias para as tags <ul> , <li> e <a> . Isso nos salva o problema de ter que defini -los.
Também é bastante comum para uma única página conter mais do que um único controle de adaptador, como um menu. Se você deseja uma aparência distinta para cada controle, defina o CSSSELECTERCLASS para o controle adaptado. Por exemplo, você pode definir o valor da propriedade CSSSELECTERCLASS da seguinte maneira:
Listagem 4 - Propriedade CSSSELECTERCLASS
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
> </ asp:Menu > O resultado é que o código HTML gerado pelo controle adaptado estará contido em uma nova camada ( <div> ).
Listagem 5 - envolver o código HTML gerado
< div class =" PrettyMenu " id =" Menu1 " >
<!-- Other HTML code -->
</ div >Observe que esta propriedade é específica para os adaptadores amigáveis do CSS. É um atributo personalizado (expando) que você pode definir para os controles suportados por esta biblioteca. É necessário mais informações sobre a maneira como os adaptadores amigáveis funcionam e, em seguida, consulte os seguintes links:
Com a classe CSSSELECTER gerando uma camada separada ( <div> ) em torno do menu e as classes CSS injetadas automaticamente no lugar, estamos finalmente prontos para iniciar o estilo do menu.
O CSS utilizado é simular ao do artigo da Apart Apart. Conforme mencionado antes do foco deste artigo, não está na estrutura do CSS, mas em como aplicá -lo ao controle do menu ASP.NET para obter um menu tabular de aparência elegante. O resultado final pode ser visto na Figura 2.
Figura 2 - o resultado final

Na página de download, você pode encontrar o código -fonte deste artigo. Ele contém a folha de estilo e as imagens necessárias. Basta executar as etapas a seguir para recriar o resultado final:
<Pages> como padrão. (Consulte Listagem 6)Listagem 6 - Trecho Web.config
< system .web>
<!-- ... -->
< pages theme = " Default " >
<!-- ... -->
</ pages >
<!-- ... -->
</ system .web>O CSS usado na minha solução é simular ao do artigo em uma lista, mas há algumas alterações. Principalmente as mudanças se correlacionam com a estrutura CSS aplicada pelos adaptadores amigáveis do CSS.
Para aplicar o CSS, a estrutura correta precisa ser usada. Ao modelar um controle cujo HTML é ajustado por um adaptador amigável, acho útil usar diagramas mencionados no papel branco. Esses diagramas mostram claramente como o CSS está estruturado.
Você pode encontrar o diagrama para o controle do menu aqui.
Uma pergunta que eu costumava ser acumulada em muitos fóruns é como implementar um sub -menu horizontal que muda quando o usuário seleciona uma guia diferente do menu de nível superior. Para criar isso, primeiro precisamos ajustar o mapa do nosso site.
A Listagem 7 mostra o mapa do site ajustado.
Listagem 7 - Web.sitemap com "itens sub -menu"
<? 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 >Para a listagem de Brevity, 7 exibe apenas os itens do sub -menu (nós) para o nó doméstico. Confira o web.sitemap no código -fonte da versão completa. Agora, quando você navega no site usando este mapa do site, verá o efeito mostrado na Figura 3.
Figura 3 - itens sub -menu

Para desativar esse efeito Defina a propriedade MaximumdynamicDisplayLeLELEs do controle de menu como zero, conforme mostrado na Listagem 8.
Listagem 8 - MaximumdynamicDisplayLevels Propriedade
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
MaximumDynamicDisplayLevels =" 0 "
> </ asp:Menu >Em seguida, adicione um segundo menu e controle do SitemApDataSource e defina suas propriedades, como mostrado na Listagem 9.
Listagem 9 - Controle do sub -menu
< 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 "
/>Basicamente, dizemos ao segundo menu que ele deve exibir o segundo nível de nós encontrados no mapa do site e que ele não deve exibir o nó inicial que corresponde à guia selecionada do primeiro menu.
Além disso, o CSSSELECTERCLASS para o segundo menu é definido como prettysubmenu. O CSS para este menu é simular ao primeiro menu. Faça o download do código -fonte se desejar conferir. A execução do site agora fornecerá esse resultado espumante.
Figura 4 - itens de sub -menu com estilo

Um último problema precisa ser resolvido. Para ilustrar esse problema, o projeto precisa ser reorganizado.
Primeiro, vamos adicionar uma página mestre ao projeto chamado site.master. Mova o código, os menus e as fontes de dados, da página padrão.aspx para a página mestre e coloque -a logo antes do primeiro titular do Content Place no corpo. Depois, você pode excluir com segurança a página padrão.aspx.
Agora, vamos adicionar alguns itens de formulário de conteúdo da web ao projeto. Adicione os formulários de conteúdo da Web que correspondem aos itens do primeiro nó do mapa do site e de seus submesa, a saber:
Certifique -se de escolher o site.master como a página mestre para cada um desses formulários de conteúdo da Web. As outras páginas mencionadas na web.Sitemap estão puramente lá para fins ilustrativos.
Inicie o site novamente e navegue até a página Foo. Isso revelará a questão.
Figura 5 - Problema de seleção

Como navegamos para o nível inferior no mapa do site, o menu de nível superior não sabe qual item de menu deve marcar conforme selecionado. Precisamos fazer alguma codificação no código da Página Master para trás para resolver isso.
A Listagem 10 mostra o pedaço de código necessário.
Listagem 10 - Selecionando o item de menu de nível superior correto
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 ;
}
}
}
}
}
}Agora você está livre para selecionar qualquer um dos itens do sub -menu. É o item de menu de nível superior correspondente será selecionado para dar ao visitante uma pista visual sobre onde ele está localizado atualmente no site.
Figura 6 - Problema de seleção corrigida

É um pouco de trabalho estabelecer um menu tabular sofisticado com um sub -menu horizontal sensível ao contexto, mas no final você acaba com um menu de aparência liso e amigável.
Sugiro que você implemente esse menu em um controle do usuário e inclua esse controle do usuário na página mestre do seu site. Na maioria dos casos, um desses menus será usado em todo o site.