Parte 3 final

    Olá pessoal, hoje gostaria de terminar a série de artigos publicados sobre o assunto de menu montado com banco de dados. As partes publicadas são seqüências usando passo a passo, isto é, desde a modelagem do banco de dados até o aparecimento do menu na tela.

    Todos estes artigos têm o objetivo de te ajudar e facilitar o desenvolvimento dessa solução web bastante usada. Todo aplicativo dinâmico e com diferenciação de usuário necessita de  um menu diferenciado ou de acordo com cada perfil do usuário.

Referência:
Ferramenta: Visual Studio .NET 2008
Linguagem: C#.NET
Banco de dados: SQL Server 2008 (mas pode ser feito em qualquer banco)
Componente web usado: ASP:MENU

Artigos publicados anteriormente
Parte 1
http://aspneti.com/Montando+Menu+Dinamico+com+Banco+de+Dados+944,0.aspx

Parte 2
http://aspneti.com/Montando+Menu+Dinamico+com+Banco+de+Dados+947,0.aspx

    Peço que leia com atenção os dois primeiros artigos, faça como foi falado para que não haja problema no momento da codificação, cujo será abordado nesta última parte.

    Na parte 2 do artigo eu coloquei um pequeno código sobre a sessão. O menu será usado daquela maneira para facilitar. Não é errado usar assim, e em muitos aplicativos tenho usado dessa forma para ter um melhor controle.


Codificação

    O primeiro passo é a parte HTML do menu. Dentro da página .aspx eu coloquei o componente menu da própria ferramenta Visual Studio .NET 2008. Coloquei também alguns css’s e cores específicas.  Referência Code 3.1.


<asp:Menu ID="MenuSistema" runat="server" DisappearAfter="4000" EnableTheming="false"
                            Orientation="Horizontal" Height="44px" Font-Names="Arial" Font-Bold="true">
                            <StaticMenuItemStyle ForeColor="#02587b" HorizontalPadding="10px" Height="28px" BorderWidth="1px"
                                BorderColor="Transparent" Font-Size="11pt" />
                            <StaticHoverStyle BackColor="Transparent" CssClass="staticHoverStyle" ForeColor="#444444"
                                BorderColor="#f8f8f8" BorderWidth="1px" />
                            <StaticSelectedStyle BackColor="#d4d4d4" ForeColor="#444444" BorderColor="Transparent"
                                BorderWidth="1px" />
                            <DynamicMenuStyle BackColor="#f5f5f5" BorderColor="#b4b4b4" BorderWidth="1px" />
                            <DynamicMenuItemStyle Height="28px" HorizontalPadding="15px" Width="100%" Font-Size="10pt"
                                ForeColor="#666666" Font-Bold="false" />
                            <DynamicHoverStyle ForeColor="#ffffff" CssClass="dynamicHoverStyle" BackColor="Transparent" />
                        </asp:Menu>

Code 3.1

    Não é necessário usar css ou cor para o menu, coloquei para ficar mais bonito e o usuário final gostar. Isso vem de cada desenvolvedor. O importante neste código é colocar o atributo DisappearAfter=”4000” e o EnableTheming=”false”.

    Note também o id do objeto da tela, vou utilizar este mesmo nome. Id=”MenuSistema”.

    No artigo 2, descrevi como preencher a sessão do menu com o select no banco de dados. Com a sessão preenchida fica fácil montar o menu. Existem alguns métodos específicos para montar o pai e o filho.


Código Load da Página

    Depois do usuário logar no aplicativo e carregar a sessão de menu, na página principal ou dentro da masterpage (que é o meu caso) eu verifico a sessão e os demais campos vindos do banco de dados. Referência Code 3.2


protected string Link = "";
if (Sessao.Menu != null)
            {
                DataTable ItensMenu = DataTableUtil.FilterDataTable(Sessao.Menu, "ItemSeguranca=false");
                foreach (DataRow ItemMenu in ItensMenu.Rows)
                {
                    if (!Convert.ToBoolean(ItemMenu["IndicadorAbertura"]))
                    {
                        Link = ItemMenu["Endereco"].ToString();
                    }
                    else
                    {
                        Link = "javascript:abreJanela('" + ItemMenu["Endereco"].ToString() + "')";
                    }

                    MenuItem menu = new MenuItem(ItemMenu["Descricao"].ToString(), ItemMenu["ObjetoId"].ToString(), "", Link);
                    if (ItemMenu["ObjetoPaiId"].ToString().Equals(""))
                    {
                        MenuSistema.Items.Add(menu);
                        AddSubMenuItem(menu, Sessao.Menu);
                    }
                }

                MenuItem menuSair = new MenuItem("Sair", "Sair", "", "Logout.aspx");
                MenuSistema.Items.Add(menuSair);
            }

Referência: Code 3.2.

    A primeira linha é verificar se a Sessao.Menu é diferente de null. Se for eu faço um filtro para o item de segurança igual à false. O passo seguinte é fazer um foreach do item menu que é do tipo DataRow nos ItensMenu.Rows retornados do filtro.

    Dentro do for, verifico com o if se o campo do banco de dados chamado IndicadorAbertura é false, eu atribuo o ItemMenu com o campo Endereco a variável Link senão eu coloco para abrir a função em javascript passando o parâmetro para abrir popup.


MenuItem menu = new MenuItem(ItemMenu["Descricao"].ToString(), ItemMenu["ObjetoId"].ToString(), "", Link);

        if (ItemMenu["ObjetoPaiId"].ToString().Equals(""))
        {
            MenuSistema.Items.Add(menu);
            AddSubMenuItem(menu, Sessao.Menu);
        }

Code 3.3

    Continuando, o code 3.3 está contido no Code 3.2. Para adicionar o menu, gerei uma nova instância do MenuItem passando a “Descricao", “ObjetoId” e o Link. O passo seguinte é verificar com um if se o campo ObjetoPaiId é igual a nada, se for eu adiciono no MenuSistema (que é o id do objeto da tela) passando a variável menu e depois chamo outro método chamado AddSubMenuItem(menu, Sessao.Menu).


protected void AddSubMenuItem(MenuItem MenuPai, DataTable dtMenu)
    {
        foreach (DataRow ItemMenu in dtMenu.Rows)
        {
            if (MenuPai.Value.ToString().Equals(ItemMenu["ObjetoPaiId"].ToString()))
            {
                if (!Convert.ToBoolean(ItemMenu["IndicadorAbertura"]))
                {
                    Link = ItemMenu["Endereco"].ToString();
                }
                else
                {
                    Link = "javascript:abreJanela('" + ItemMenu["Endereco"].ToString() + "')";
                }

                MenuItem menu = new MenuItem(ItemMenu["Descricao"].ToString(), ItemMenu["ObjetoId"].ToString(), "", Link);
                MenuPai.ChildItems.Add(menu);
                AddSubMenuItem(menu, Sessao.Menu);
            }
        }
    }
Referência: Code 3.4

    O code 3.4 mostra especificamente o método AddSubMenuItem. Responsável por adicionar um submenu dentro de um menu principal. É necessário passar o MenuItem e a Sessao.Menu (DataTable).

    Dentro dele que faço um for seguindo o mesmo procedimento feito no menu anterior. No final do método, exatamente na última linha eu chamo o mesmo método passando os dados.

    Você pode usar um skin para atribuir um layout legal, css, imagens e tudo mais.  Lembre-se que, para preencher o menu de acordo com o usuário é necessário passar o id do usuário logado e fazer o select mostrado no artigo 2. Veja o código de como atribuir valor para a sessão. Referência Code 3.5.

Sessao.Menu = new ObjetoBRL().BuscaMenuDoUsuario(Sessao.UsuarioId);
Referência: Code 3.5

    É bem simples e fácil depois que já tenho o banco de dados. Segue a minha página completa para que tenha uma noção. Referência Code 3.6 (Principal.master)

 
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class MeuAplicativo : System.Web.UI.MasterPage
{
    protected string Link = "";

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Sessao.UsuarioLogado || Sessao.UsuarioId.Equals(0))
        {
            Response.Redirect("Default.aspx");
        }
        if (!IsPostBack)
        {
            if (Sessao.Menu != null)
            {
                DataTable ItensMenu = DataTableUtil.FilterDataTable(Sessao.Menu, "ItemSeguranca=false");
                foreach (DataRow ItemMenu in ItensMenu.Rows)
                {
                    if (!Convert.ToBoolean(ItemMenu["IndicadorAbertura"]))
                    {
                        Link = ItemMenu["Endereco"].ToString();
                    }
                    else
                    {
                        Link = "javascript:abreJanela('" + ItemMenu["Endereco"].ToString() + "')";
                    }

                    MenuItem menu = new MenuItem(ItemMenu["Descricao"].ToString(), ItemMenu["ObjetoId"].ToString(), "", Link);
                    if (ItemMenu["ObjetoPaiId"].ToString().Equals(""))
                    {
                        MenuSistema.Items.Add(menu);
                        AddSubMenuItem(menu, Sessao.Menu);
                    }
                }

                MenuItem menuSair = new MenuItem("Sair", "Sair", "", "Logout.aspx");
                MenuSistema.Items.Add(menuSair);
            }
        }
    }
   
    protected void AddSubMenuItem(MenuItem MenuPai, DataTable dtMenu)
    {
        foreach (DataRow ItemMenu in dtMenu.Rows)
        {
            if (MenuPai.Value.ToString().Equals(ItemMenu["ObjetoPaiId"].ToString()))
            {
                if (!Convert.ToBoolean(ItemMenu["IndicadorAbertura"]))
                {
                    Link = ItemMenu["Endereco"].ToString();
                }
                else
                {
                    Link = "javascript:abreJanela('" + ItemMenu["Endereco"].ToString() + "')";
                }

                MenuItem menu = new MenuItem(ItemMenu["Descricao"].ToString(), ItemMenu["ObjetoId"].ToString(), "", Link);
                MenuPai.ChildItems.Add(menu);
                AddSubMenuItem(menu, Sessao.Menu);
            }
        }
    }
}

Referência: Code 3.7

    Depois da masterpage criada, basta criar a página .aspx como por exemplo (default.aspx) e indicar a master page do projeto. O resultado final é o menu montado. Referência Image 3.8.


Referência: Image 3.8

    Bom, fico por aqui e espero que tenha gostado. Qualquer dúvida pode entrar em contato pelo site.