Posted by: Sr Coelho | 09/07/2013

Menu HTML Dinâmico com ASP .NET MVC C#

No passado já havíamos falado sobre o assunto em menu dinâmico em c#, que trava de criar um menu dinâmico utilizando o componente System.Web.UI.WebControls.Menu do .Net.

Agora vamos mostrar como criar um menu semelhante, porém em HTML, utilizando apenas as tags <ul> e <li>. O menu criado dessa forma apresenta várias vantagens em relação ao outro, que utiliza componente. A vantagem mais importante é que com código HTML, você pode estilizar o menu como bem entender, utilizando todo poder do JavaScript, além de não ficar limitado aos métodos e propriedades que um componentes pode oferecer. O projeto foi criado na estrutura ASP .NET MVC 4, utilizando Visual Studio 2012.

O código é bastante simples e se resume basicamente em  4 métodos, localizados dentro do controller Home (HomeController.cs);

public ActionResult Index()
{
    string meuMenu = string.Empty;

    menuLista = PesquisarDadosMenu();

    if (menuLista != null && menuLista.Count > 0)
    {
        meuMenu = CriarMenu();
    }

    return View((object)meuMenu);
}

O primeiro método a ser executado, quando o usuário acessa a aplicação web é o Index(). Esse método aciona a pesquisa do menu, e caso seja retornado algum valor na lista de menus, ele aciona o método para criação do menu. No final, ele retorna a string que representa o menu em HTML para a View.

private List</pre>
<menu>PesquisarDadosMenu()
{
 List
<menu>menuLista = new List
<menu>();

 menuLista.Add(new Menu(1, "Dicas do Sr. Coelho", string.Empty, 0));
 menuLista.Add(new Menu(2, "Dica1", "https://srcoelho.com.br/2013/01/11/dica-para-obter-desconto-na-compra-online", 1));
 menuLista.Add(new Menu(3, "Dica2", "https://srcoelho.com.br/2012/12/23/imagens-no-gmail", 1));
 menuLista.Add(new Menu(4, "Dica3", "https://srcoelho.com.br/2012/08/26/dicas-transito", 1));
 menuLista.Add(new Menu(5, "Dica4", "https://srcoelho.com.br/2011/09/10/teste-de-velocidade-de-internet", 1));

 menuLista.Add(new Menu(6, "Artigos do Sr. Coelho", string.Empty, 0));
 menuLista.Add(new Menu(7, "Artigo 1", string.Empty, 6));
 menuLista.Add(new Menu(8, "Artigo 1.1", string.Empty, 7));
 menuLista.Add(new Menu(9, "Artigo 1.1.1", string.Empty, 8));
 menuLista.Add(new Menu(10, "Artigo 1.1.2", string.Empty, 8));

 menuLista.Add(new Menu(11, "Artigo 2", string.Empty, 6));
 menuLista.Add(new Menu(12, "Artigo 2.1", string.Empty, 11));
 menuLista.Add(new Menu(13, "Artigo 2.2", string.Empty, 11));
 menuLista.Add(new Menu(14, "Artigo 2.3", string.Empty, 11));
 menuLista.Add(new Menu(15, "Artigo 2.3.1", string.Empty, 14));

 return menuLista;
}

O método PesquisarDadosMenu() simula uma consulta no banco de dados para buscar o menu a ser criado. Ele retorna uma coleção de objetos do tipo Menu. Em um cenário real, o sistema faria a consulta no banco de dados utilizando o Entity Framework e baseado em critérios de pequisa (como id do usuário, por exemplo), retornaria a lista com os objetos do menu a ser criado. Veja a classe Menu.cs em Models para entender cada propriedade do modelo menu.

private string CriarMenu()
{
    StringWriter stringWriter = new StringWriter();
    HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Ul);

    foreach (var menuItem in menuLista.Where(m => m.MenuPai == 0))
    {
        CriarSubMenu(htmlWriter, menuItem);
    }

    htmlWriter.RenderEndTag(); //UL
    return stringWriter.ToString();
}

O método CriarMenu inicia a criação do menu. As tags Html serão escritas no lado servidor, através do controle HtmlTextWriter e serão utilizadas as seguintes tags <ul> e <li>. Segue uma referência para você entender mais sobre essas tags.

O método percorre a lista de menus criada no passo anterior, porém ele percorre apenas os itens de menu que são root, ou seja, não possuem pai. Esses níveis serão os primeiros níveis da árvore de menu. Para cada item de menu root encontrado o método CriarSubMenu é acionado.

private void CriarSubMenu(HtmlTextWriter htmlWriter, Menu itemCorrente)
{
    var listaFilhos = menuLista.Where(m => m.MenuPai == itemCorrente.Id);
    bool temFilho = listaFilhos.Count() > 0;

    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Li);

    MontarItemMenu(htmlWriter, itemCorrente);

    if (temFilho)
        htmlWriter.RenderBeginTag(HtmlTextWriterTag.Ul);

    foreach (var itemFilho in listaFilhos)
    {
        CriarSubMenu(htmlWriter, itemFilho);
    }

    if (temFilho)
        htmlWriter.RenderEndTag(); //UL

    htmlWriter.RenderEndTag(); //LI
}

CriarSubMenu é o engine dessa aplicação, é nele que ocorre a “mágica” para montar o menu dinâmico de maneira recursiva. A recursividade permite que não haja nível máximo de nós no menu, ele pode ter infinitos subníveis. Veja que o sistema verifica se o item de menu corrente tem filhos, e em caso positivo, ele percorre a lista de filhos acionando novamente ele mesmo (CriarSubMenu).

Basicamente esses são os 4 métodos que merecem uma atenção maior. o restante pode ser entendido analisando o código da aplicação, anexo ao final desse artigo.

Lembrando que o resultado dessa aplicação, é um menu sem estilo, como na imagem abaixo.

menu_html_sem_estilo

A partir disso, você deve estilizar o menu usando javascript e css, por exemplo. Assim, de acordo com o estilo aplicado, o menu pode assumir o formato que mais se adequa à sua necessidade.

*Em breve iremos disponibilizar uma versão estilizada com alguns links de referência dos estilos utilizados. Inscreva-se no menu ao lado para acompanhar as atualizações do blog.

Google Drive png 16x16Download from Google Drive

Github 16x16

Download from GitHub


SrCoelho

Curtiu? Visite Artigos do Sr. Coelho para mais dicas.


Responses

  1. Essa forma é muito melhor que a outra. Mas seria possível fazer usando web forms?

    • Seria sim Cassiano, o código acima seria facilmente adaptado para Web Forms. Em breve posso fazer uma versão assim…

  2. No caso de projetos ASP.NET MVC recomendo usar HTML Helps.

    Ex:
    Classe MenuHelper
    public static MvcHtmlString Menu(this HtmlHelper helper)
    {
    DataContext db = new DataContext();

    var sb = new StringBuilder();
    sb.Append(“”);
    var grupos = from g in Roles.GetRolesForUser().AsQueryable() select new RoleModel() { Name = g }; ;
    foreach (RoleModel grupo in grupos)
    {

    var menusInRole = from rm in db.RolesMenus
    where rm.RoleName.Equals(grupo.Name) && rm.MainMenuId==0
    select rm;

    foreach (RoleMenuModel MnuGrupo in menusInRole)
    {
    MenuModel _menu = db.Menus.Where(m => m.id == MnuGrupo.MenuId).OrderBy(m => m.Order).FirstOrDefault();
    if (_menu != null)
    {
    sb.AppendLine(“”);
    string strHref = string.Format(“{1}“, _menu.Url, helper.Encode(_menu.Title));
    sb.AppendFormat(strHref);
    sb.AppendLine(“”);

    }
    }
    }

    sb.Append(“”);
    db.Dispose();

    return MvcHtmlString.Create(sb.ToString());
    }

    }

    Chamando o Menu na página do template do site “_Layout.cshtml”.

    ….

    Custom Authorize

    @Html.Partial(“_LogOnPartial”)

    @Html.Menu()

    @RenderBody()

    Neste exemplo o menu é montando de acordo com as permissões do usuário.

    Espero te ajudado.

    George Lnes

  3. Cara preciso muito de fazer um menu dinamico formatado usei seu modelo mais estou com dificuldades para emplementar os estilos

    • Olá Michael,

      Eu posso te ajudar, basta descrever como você deseja este menu.

      Me mande e-mail com o que você precisa: georgelanes@gmail.com.

      Abs


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: