Desenvolvimento - ASP. NET

Criando um Menu personalizado para suas aplicações Asp.NET

Neste artigo o autor apresenta uma nova forma de criar menus atraentes utilizando o componente SkmMenu em ASPNET de maneira bastante simples e didática.

por Igor Musardo



Quando se desenvolve uma aplicação Web, é comum que você necessite de um menu que possibilite impactar positivamente os usuários com beleza e requinte. Nesse artigo vou explicar como criar um menu atraente em Asp.NET.

Como o exemplo abaixo, selecionei dois cenários com menus que utilizam o mesmo componente e produzem resultados tão diferentes.

Figura 1 – Menu simples

Figura 2 – Menu estilo Office 2007

O componente que gerou esses menus se chama SKM Menu, disponível em http://www.skmmenu.com, esse componente é freeware / open source e teve a sua última versão lançada em 21 de fevereiro de 2004. Embora a primeira impressão seja a de um projeto inativo por causa do longo período sem atualizações, o SKM Menu na verdade é um projeto estabilizado, compatível com o frameworks .NET 2.0.

Já utilizo esse componente em minhas aplicações a um bom tempo, e nesse período consegui desenvolver uma técnica interessante de como tirar um maior proveito do componente, e quero compartilhar essa técnica com os leitores através desse artigo.

O objetivo é que ao final do artigo tenhamos conseguido um menu semelhante ao da figura 2. Porém o primeiro passo será criarmos um menu com o modelo da figura1.

O primeiro passo é fazer o download do binário (DLL) do componente no site, e criar uma aplicação Asp.NET no Visual Studio 2005. Eu utilizarei o Vb.NET como linguagem para meu exemplo.

Após criar a aplicação, você deve colocar o arquivo skmMenu.dll que você acabou de baixar dentro da pasta BIN da sua aplicação como na figura abaixo.


Figura 3 – skmMenu.DLL dentro da pasta Bin.

Não estranhe se na imagem estiver um pouco diferente do que o seu Visual Studio esteja mostrando, pois utilizo o Visual Studio 2005 com o Service Pack 1 instalado.

Agora na ToolBox você deve clicar com o botão direito e clicar em “Add Tab” coloque o nome “SkmMenu” para essa tab. Como na figura abaixo.

Figura 4 – ToolBox com a tab “SkmMenu”

Clique novamente com o botão direito, agora dentro da tab que acabamos de criar e clique em “Choose Items...”, a próxima janela (Figura 5) demora alguns segundos para aparecer.

Figura 5 – Choose Toolbox Items

Clique em “Browse...”, selecione o arquivo skmMenu.dll dentro da pasta Bin da sua aplicação e clique em “Open” e em seguida em “Ok”.

O resultado deve ser igual ao da Figura 6.

Figura 6 – Toolbox com o componente vinculado.

Clique e arraste o componente Menu para dentro da sua página Default.aspx que já deve estar aberta em modo Design. O Visual Studio exibirá o componente com 5 Menu Item na vertical. Se você não fizer mais nada e rodar a aplicação, a tela virá em branco, pois não preenchemos o menu com nenhuma informação.

Você pode verificar que esse componente possui inúmeras propriedades na caixa de Propriedades do Visual Studio. Aproveite que está com a caixa de Propriedades aberta, altere a Id do componente para MnuPrincipal.

O SkmMenu utiliza arquivos XML como DataSource, então antes de criarmos o XML do menu vamos entender a estrutura que o SkmMenu reconhece.


<menu>
    <menuItem>
    
     ... Menu Item 1 ...
    </menuItem>
    <menuItem>
    
     ... Menu Item 2 ...
    
     <subMenu>
    
       <menuItem>
    
         ... Menu Item 3 ...
    
       </menuItem>
    
     </subMenu>
    </menuItem>

                    
  ...
</menu>

Tabela 1 – Estrutura XML que o SkmMenu interpreta.

Conforme mostra a Tabela 1, a estrutura do XML possui tags próprias do componente como, por exemplo, <menu> <menuItem> e <subMenu>. Cada <menuItem> pode conter vários elementos de propriedades. Abaixo disponibilizei uma tabela com os elementos de propriedades do menuItem que está disponível no site do componente. Quando for utilizá-los lembre que XML é case-sensitive!

Elemento XML

Propriedade

Exemplo

<text>

Text

<text>Sobre</text>

<url>

Url

<url>http://www.asp.net</url>

<target>

Target

<target>_blank</target>

<image>

Image

<image>/imagens/menu.gif</image>

<imagealttext>

ImageAltText

<imagealttext>Texto</imagealttext>

<commandname>

CommandName

<commandname>Delete</commandname>

<javascriptcommand>

JavaScriptCommand

<javascriptcommand>foobar</javascriptcommand>

<tooltip>

ToolTip

<tooltip>Aprenda sobre skmMenu!</tooltip>

<cssclass>

CssClass

<cssclass>silverClass</cssclass>

<mouseovercssclass>

MouseOverCssClass

<mouseovercssclass>silverClass</mouseovercssclass>

<mouseupcssclass>

MouseUpCssClass

<mouseupcssclass>silverClass</mouseupcssclass>

<mousedowncssclass>

MouseDownCssClass

<mousedowncssclass>silverClass</mousedowncssclass>

<mouseoverimage>

MouseOverImage

<mouseoverimage>over.jpg</mouseoverimage>

<mouseupimage>

MouseUpImage

<mouseupimage>up.jpg</mouseupimage>

<resolveurl>

ResolveUrl

Apenas pode ser: <resolveurl>true</resolveurl> or <resolveurl>false</resolveurl>

<enabled>

Enabled

Apenas pode ser:
<enabled>true</enabled> or <enabled>false</enabled>

<visible>

Visible

Apenas pode ser:
<visible>true</visible> or <visible>false</visible>

<leftimage>

LeftImage

<leftimage>someImage.png</leftimage>

<rightimage>

RightImage

<rightimage>someImage.png</rightimage>

<rightimageleftpadding>

RightImageLeftPadding

<rightimageleftpadding>Valor</rightimageleftpadding>

<leftimagerightpadding>

LeftImageRightPadding

<leftimagerightpadding>Valor</leftimagerightpadding>

<rightimagealign>

RightImageAlign

<rightimagealign>Valor</rightimagealign>

<leftimagealign>

LeftImageAlign

<leftimagealign>Valor</leftimagealign>

<horizontalalign>

HorizontalAlign

<horizontalalign>Convertable to HorizontalAlign</horizontalalign>

<verticalalign>

VerticalAlign

<verticalalign>Valor</verticalalign>

<width>

Width

<width>Valor</width>

<height>

Height

<height>Valor</height>

<roles>

Roles

<roles>Delimitado por vírgula</roles> Ex: <roles>dev,test,manager</roles>

<backcolor>

BackColor

<backcolor>Nome da cor</backcolor>

<bordercolor>

BorderColor

<bordercolor> Nome da cor </bordercolor>

<borderwidth>

BorderWidth

<borderwidth>Valor</borderwidth>

Tabela 2 – Elementos de propriedade do menuItem.

Após conhecermos a estrutura do XML vamos criar um arquivo chamado “menu.xml” com o seguinte código:

<?xml version="1.0" encoding="utf-8"?>

<menu>

<menuItem>

<text>Home</text>

<url>default.aspx</url>

</menuItem>

<menuItem>

<text>Página 1</text>

<subMenu>

<menuItem>

<text>Página 1.1</text>

</menuItem>

<menuItem>

<text>Página 1.2</text>

</menuItem>

</subMenu>

</menuItem>

</menu>

Tabela 3 – menu.xml

Após criar esse arquivo, vamos colocá-lo como datasource do nosso MnuPrincipal. No arquivo Default.aspx.vb insira dentro da Sub Page_Load o seguinte código.

MnuPrincipal.DataSource = Server.MapPath("menu.xml")

MnuPrincipal.DataBind()

Tabela 4 – Tornar o menu.xml datasource do MnuPrincipal e preencher o componente.

Agora salve os arquivos abertos e rode a aplicação. O resultado esperado é esse:

Figura 7 – Menu funcionando.

Funcionou! Porém sem nenhum atrativo visual. Vamos começar a incrementar esse menu com um pouco de CSS. Porém antes, vamos mudar o Layout do menu, de Vertical vamos passar para Horizontal. Para isso vá na janela de propriedades do componente, procure a propriedade Layout e altere de Vertical para Horizontal como mostra a figura abaixo.

Figura 8 – Layout do Menu

Ainda dentro da caixa de propriedades, expanda as propriedades SelectedMenuItemStyle e UnselectedMenuItemStyle e coloque o nome das classes CSS MenuSelecionado e Menu subseqüentemente, conforme a figura a seguir:

Figura 9 – Alterando as CssClass do MnuPrincipal

Agora vamos criar essas classes CSS em um novo arquivo de estilos. Na caixa Solution Explorer adicione um novo arquivo chamado estilo.css e insira o seguinte código.

.Menu

{

background-color:Black;

color:White;

text-decoration: none;

cursor: hand;

font-family: Verdana;

font-size: 10px;

height: 18px;

background-repeat: repeat;

}

.MenuSelecionado

{

background-color:#886611;

color:White;

text-decoration: none;

cursor: hand;

font-family: Verdana;

font-size:10px;

height:18px;

background-repeat: repeat;

}

Tabela 5 – estilo.css.

Vincule sua página Default.aspx ao estilo.css, simplesmente arrastando o arquivo CSS do Solution Explorer para dentro da página ASPX aberta no modo Design.

Execute a aplicação para ver o resultado, que deve ser parecido com o seguinte.

Figura 10 – Menu com estilo CSS aplicado.

Caso o seu menu não tenha aparecido na horizontal, coloque a propriedade Layout="Horizontal" diretamente no source da página ASPX. O seu código deve ficar assim.

<cc1:Menu ID="MnuPrincipal" runat="server" Layout="Horizontal">

<UnselectedMenuItemStyle CssClass="Menu" />

<SelectedMenuItemStyle CssClass="MenuSelecionado" />

</cc1:Menu>

Tabela 6 – Default.aspx.

Finalmente nosso menu ficou parecido com o modelo da Figura 1, agora vamos deixá-lo como o menu da Figura 2.

O primeiro passo da segunda etapa é fazermos uma pequena alteração no arquivo estilo.css, acrescentando a propriedade background-image nas duas classes, faça o download das imagens através desse link e descompacte os arquivos dentro da pasta imagens dentro do nosso projeto..

.Menu

{

background-image: url(imagens/img_fnd_menu.gif);

text-decoration: none;

cursor: hand;

font-family: Verdana;

font-size: 10px;

height: 18px;

background-repeat: repeat;

}

.MenuSelecionado

{

background-image: url(imagens/img_fnd_menu.gif);

text-decoration: none;

cursor: hand;

font-family: Verdana;

font-size: 10px;

height: 18px;

background-repeat: repeat;

}

Tabela 7 – estilo.css.

Rodando nossa aplicação percebemos o seguinte resultado.

Figura 11 – Após alteração no arquivo estilo.css.

Agora iremos definir como será o formato do nosso SubMenu. O primeiro passo é criar a estrutura em HTML conforme o código abaixo.

<table class="SubMenuBorder" cellpadding="0" cellspacing="0">

<tr>

<td><img src="imagens/img_submenu_cnt_esq_sup.gif" width="3" height="3" /></td>

<td><img src="imagens/img_submenu_cnt_sup.gif" width="227" height="3" /></td>

<td><img src="imagens/img_submenu_cnt_dir_sup.gif" width="3" height="3" /></td>

</tr>

</table>

<table class="SubMenu">

<tr>

<td width="28" align="center"><img id="subMenu_1" src="imagens/add_off.png" /></td>

<td width="5"></td><td width="200">Página 1.1</td>

</tr>

</table>

<table class="SubMenu">

<tr>

<td width="28" align="center"><img id="subMenu_2" src="imagens/accept_off.png" /></td>

<td width="5"></td><td width="200">Página 1.2</td>

</tr>

</table>

<table class="SubMenuBorder" cellspacing="0" cellpadding="0">

<tr>

<td><img src="imagens/img_submenu_cnt_esq_inf.gif" width="3" height="3" /></td>

<td><img src="imagens/img_submenu_cnt_inf.gif" width="227" height="3" /></td>

<td><img src="imagens/img_submenu_cnt_dir_inf.gif" width="3" height="3" /></td>

</tr>

</table>

Tabela 8 – HTML do SubMenu.

Cujo resultado esperado é.

Figura 12. SubMenu.

Agora vamos fazer mais algumas alterações no arquivo estilo.css.

table{

border-collapse: collapse;

border-spacing: 0px;

}

table tr td {

padding:0px;

font-size:10px;

}

.Menu

{

background-image: url(imagens/img_fnd_menu.gif);

background-repeat: repeat;

text-decoration: none;

cursor: hand;

font-family: Verdana;

font-size: 10px;

text-align:center;

padding:0px;

margin:0px;

height:26px;

width:100px;

}

.MenuSelecionado

{

background-image: url(imagens/img_fnd_menu.gif);

background-repeat: repeat;

text-decoration: none;

cursor: hand;

font-family: Verdana;

font-size: 10px;

text-align:center;

padding:0px;

margin:0px;

height:26px;

width:100px;

}

.SubMenu

{

background-image: url(imagens/btn_menu_submenu_fundo.gif);

text-decoration: none;

cursor: hand;

font-family: Verdana;

font-size: 10px;

background-repeat: repeat;

border:0px;

margin:0px;

height:23px;

padding:0px;}

.SubMenuSelecionado

{

background-image: url(imagens/btn_menu_submenu_ativo_fundo.gif);

text-decoration: none;

cursor: hand;

font-family: Verdana;

font-size: 10px;

background-repeat: repeat;

border:0px;

margin:0px;

height:23px;

padding:0px;

}

.SubMenuIcone

{

width:28px;

text-align:center;

}

.SubMenuConteudo

{

width:200px;

text-align:left;

}

.SubMenuBorda

{

width:233px;

text-align:left;

}

Tabela 9 – Estilo.css.

Após vincular o nosso novo estilo.css ao SubMenu temos.

Figura 13. SubMenu com CSS aplicado.

Vamos incrementar nosso SubMenu incluindo um pequeno código JavaScript dentro da tag <TR> de cada SubMenu para que ao passar do mouse a figura do menu altere, conforme o código abaixo.

<table class="SubMenu">

<tr onmouseover="javascript:subMenu_1.src="imagens/add.png";" onmouseout="javascript:subMenu_1.src="imagens/add_off.png";">

<td width="28" align="center"><img id="subMenu_1" src="imagens/add_off.png" /></td>

<td width="5"></td>

<td width="200">Página 1.1</td>

</tr>

</table>

<table class="SubMenu">

<tr onmouseover="javascript:subMenu_2.src="imagens/accept.png";" onmouseout="javascript:subMenu_2.src="imagens/accept_off.png";">

<td width="28" align="center"><img id="subMenu_2" src="imagens/accept_off.png" /></td>

<td width="5"></td>

<td width="200">Página 1.2</td>

</tr>

</table>

Tabela 10 – SubMenu com JavaScript.

Agora temos o seguinte resultado.

Figura 14. SubMenu com JavaScript.

Agora que já estruturamos o nosso SubMenu, vamos incluir o código HTML dele dentro da estrutura XML.

Então para cada tabela que criamos dentro do SubMenu criaremos um menuItem, o código HTML deve ser inserido dentro da propriedade text e os caracteres < e > devem ser alterados para &lt; e &gt; e definiremos as classes CSS para cada um desses menuItem como descrito no código abaixo.

<?xml version="1.0" encoding="utf-8"?>

<menu>

<menuItem>

<text>Home</text>

</menuItem>

<menuItem>

<text>Página 1</text>

<subMenu>

<menuItem>

<text>&lt;table class="SubMenuBorda"&gt;&lt;tr&gt;&lt;td width="3"&gt;&lt;img src="imagens/img_submenu_cnt_esq_sup.gif" width="3" height="3"&gt;&lt;/td&gt;&lt;td background="imagens/img_submenu_cnt_sup.gif"&gt;&lt;img src="imagens/img_submenu_cnt_sup.gif" width="3"&gt;&lt;/td&gt;&lt;td width="3"&gt;&lt;img src="imagens/img_submenu_cnt_dir_sup.gif" width="3" height="3"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</text>

<cssclass>SubMenuBorda</cssclass>

<mouseovercssclass>SubMenuBorda</mouseovercssclass>

</menuItem>

<menuItem>

<text>&lt;table&gt;&lt;tr onmouseover="javascript:subMenu_1.src="imagens/add.png";" onmouseout="javascript:subMenu_1.src="imagens/add_off.png";"&gt;&lt;td class="SubMenuIcone"&gt;&lt;img id="subMenu_1" src="imagens/add_off.png"&gt;&lt;/td&gt;&lt;td width="5"&gt;&lt;/td&gt;&lt;td class="SubMenuConteudo"&gt;Página 1.1&lt;/td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</text>

<mouseovercssclass>SubMenuSelecionado</mouseovercssclass>

<cssclass>SubMenu</cssclass>

</menuItem>

<menuItem>

<text>&lt;table&gt;&lt;tr onmouseover="javascript:subMenu_2.src="imagens/accept.png";" onmouseout="javascript:subMenu_2.src="imagens/accept_off.png";"&gt;&lt;td class="SubMenuIcone"&gt;&lt;img id="subMenu_2" src="imagens/accept_off.png"&gt;&lt;/td&gt;&lt;td width="5"&gt;&lt;/td&gt;&lt;td class="SubMenuConteudo"&gt;Página 1.1&lt;/td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</text>

<mouseovercssclass>SubMenuSelecionado</mouseovercssclass>

<cssclass>SubMenu</cssclass>

</menuItem>

<menuItem>

<text>&lt;table class="SubMenuBorda"&gt;&lt;tr&gt;&lt;td width="3"&gt;&lt;img src="imagens/img_submenu_cnt_esq_inf.gif" width="3" height="3"&gt;&lt;/td&gt;&lt;td background="imagens/img_submenu_cnt_inf.gif"&gt;&lt;img src="imagens/img_submenu_cnt_sup.gif" width="3"&gt;&lt;/td&gt;&lt;td width="3"&gt;&lt;img src="imagens/img_submenu_cnt_dir_inf.gif" width="3" height="3"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</text>

<cssclass>SubMenuBorda</cssclass>

<mouseovercssclass>SubMenuBorda</mouseovercssclass>

</menuItem>

</subMenu>

</menuItem>

</menu>

Tabela 11 – Menu.xml com a estrutura do SubMenu.

O código realmente fica um pouco confuso, porém seguindo os passos descritos acima utilizando a técnica de desenvolver passo a passo fica bem claro qual a funcionalidade de cada código.

Rode a aplicação agora. O resultado esperado é a figura abaixo.

Figura 15 – Menu com estilo CSS aplicado e novo XML.

Percaba que o menu ainda não ficou como gostaríamos. Vamos alterar somente mais duas propriedades do nosso objeto MnuPrincipal, o ItemPadding = “0” e o ItemSpacing = “0” no source de nossa página para aí sim finalizarmos nosso trabalho.

<cc1:Menu ID="MnuPrincipal" runat="server" Layout="Horizontal" ItemPadding="0" ItemSpacing="0" >

<UnselectedMenuItemStyle CssClass="Menu" />

<SelectedMenuItemStyle CssClass="MenuSelecionado" />

</cc1:Menu>

Tabela 12 – Default.aspx.

Execute novamente o projeto.

Figura 16 – Menu final.

Pronto! Criamos um menu personalizado e bastante agradável aos olhos do cliente com o componente SkmMenu e todo o poder do HTML + JavaScript + CSS.

Mas, como nem tudo são flores, se você acessar esse menu utilizando o navegador Firefox, perceberá que o subMenu ficará sobre o Menu, para resolver esse problema, remova a seguinte linha do arquivo Default.aspx.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Tabela 13 – Default.aspx.

Pode conferir que agora a sua aplicação ficou compatível com o Firefox.

Espero nesse artigo ter conseguido exemplificar como podemos explorar funcionalidades do componente SkmMenu utilizando HTML + JavaScript + CSS indo além do que o fabricante do componente propõem em sua documentação oficial.

Como desafio, sugiro que implemente esse modelo em sua aplicação, porém criando o XML a partir de uma consulta ao seu banco de dados favorito, dando assim muito mais flexibilidade ao seu software no quesito permissão de acesso.

Forte abraço e divirta-se!

Igor Musardo

Email: ivm@onda.com.br

Baixe o código de exemplo.