Menu dinamico com diversos niveis

 :: Programando :: C Sharp

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

Menu dinamico com diversos niveis

Mensagem por terra.jr em Qua 25 Jan - 11:54

Amigos, tenho um desafio de nível quase intermediário para todos!
Construir uma solução de menus com diversos níveis de forma dinâmica com usando ASP .NET,
buscando informações disponibilizadas de fontes externas (banco de dados, cloud computing, etc).

Calma que é simples. vou explicar...

Imaginem a situação:
Você tem uma tabela chamada MENU com a seguinte estrutura:

Código:
NOME  TIPO  TAM  DESCRICAO
 idmenu  NUMERO  11  ID DO MENU
 url  TEXTO  255  URL DA PAGINA QUE SERÁ ABERTA
 idusuario  NUMERO  11  ID DO USUARIO AO QUAL O MENU PERTENCE
 menu  TEXTO  40  NOME EXIBIDO NO MENU
 tooltip  TEXTO  255  LEGENDA EXIBIDA quando O MOUSE FICAR SOBRE
 icone    TEXTO  255  URL ONDE ESTA O ICONE Q SERA EXIBIDO
 idpai    NUMERO  11  ID DO MENU QUE ESTÉ SERÁ FILHO

Ok, até aqui temos a tabela MENUS que contém os menus.
Então uma classe fará acesso ao banco de dados para obter os dados dos menus cadastrados para aquele usuário.
Após isso a classe irá criar um Objeto System.Web.UI.WebControls.Menu e preencher sua colecao Menu.Items com os menus lidos na tabela menus.

Veja que o campo IDPAI guardará o ID do menu que é o Pai. OS que tiverem o IdPai como 0, serão os que será exibidos no primeiro nível. Os que ficariam no ROOT /

Por exemplo, imagine a tabela preenchida desta forma:
Código:
ID  MENU    IDPAI
1 - Cadastros  0
2 - Consultas  0
4 - Pecas  1
5 - Produtos  1
6 - Vendas  2

Assim teriamos dentro do menu:
1-cadastro os submenus 4-pecas e 5-produtos, e no menu 2-consultas teriamos o submenu 6-vendas

Visualmente ficaria assim:
1 - Cadastro
1.1 - Pecas
1.2 - Produtos
2-Consultas
2.1 - Vendas

Entendido?

Agora ai que está o problema.
Veja que tenho como requisito (questões técnicas) que pegar a lista de MENUS em uma única pesquisa SQL.
Não posso pesquisar os registros que tem IDPAI = 0, depois percorrer os ID pais e pesquisar os filhos!
Assim eu faria diversos SQL numa única exibição do menu!

Então montei um cenário bem SIMPLES mas com um lógica incompleta!
Gostaria de saber quais as ideias para melhorar o método que alimentará o menu em tempo de execução?

Temos então o seguinte, o metodo 'dados.getDataTable(sql)' retorna um DataTable preenchido com o SQL passado como parametro.

Assim temos o seguinte código C#:

Código:
// SELECT que pega os dados dos menus em ordem de IDPAI, assim temos os PAIS primeiros, depois os filhos...
string sql = "SELECT * FROM menus WHERE idusuario=1 ORDER BY idpai ASC";

// Preenche datatable com os menus
  DataTable dt = dados.getDataTable(sql);

// Pega quantidade de menus cadastrados
  int registros = dt.Rows.Count;

// Cria menu para obter os dados
Menu menu = new Menu();

// Faremos a leitura de todos os registros do DataTable
for (int i = 0; i < registros; i++) {
// Atribui os dados de cada menu
string idpai = dt.Rows[i]["idpai"].ToString();
    string idmenu = dt.Rows[i]["idmenu"].ToString();
    string url = dt.Rows[i]["url"].ToString();
    string menu = dt.Rows[i]["menu"].ToString();
    string tooltip = dt.Rows[i]["tooltip"].ToString();
    string ativo = dt.Rows[i]["ativo"].ToString();
    string icone = dt.Rows[i]["icone"].ToString();

// AQUI ESTA O PROBLEMA, SABEMOS QUE PRIMEIRAMENTE SERAO INSERIDOS
// OS QUE TEM IDPAI=0, QUE são OS MENUS QUE FICARAO NA RAIZ (PRIMEIRO NIVEL)
// MAS COMO COLOCAR OS MENUS FILHOS QUE POSSUIM IDPAI>0 NOS MENUS PAIS CORRESPONDENTES?


// Cria novo item para ser inserido no menu.
MenuItem item = new MenuItem(menu, idmenu, icone, url);
    item.ToolTip = tooltip; // aparece quando o mouse fica sobre o menu!

    int paiSel = int.Parse(idpai);
// SE IDPAI for maior que 0 quer dizer que é um submenu.
if (paiSel > 0) {
      // AQUI ESTA A ZICA!!!
// eu sei qual é o IDPAI e tambem ate o nome do menu pai, mas não dá pra captura-lo!!!
// Pra inserir um submenu nele, pois ele foi criado agora!
} else {
menu.Items.Add(item);
}
Dessa forma, eu poderia criar diversos níveis de submenus apenas inserindo os dados na tabela!!! Sem ter que se preocupar com mudanças no site, pois a manutenção do menu como diversos itens do site seriam dinâmicas, assim fica mais flexível a utilidade do software.

Espero que tenham entendido.! Se alguém saber como fazer isso! Ou se tem outra forma!!
Mas sem utilizar ferramentas de terceiros, o tema do desafio é usar o 'System.Web.UI.WebControls.Menu'.





--------------------------------------------------

Eu fiz um que ficou um pouco escroto, mas veja:

Código:


string sql = "SELECT * FROM usuariosmenus WHERE idusuario=1 ORDER BY idpai;";
    DataTable dt = dados.getDataTable(sql); // DataTable com os dados do menu desse usuário
    int registros = dt.Rows.Count;

    // Se tiver algum registro (algum menu)
    if (registros > 0) {
    m.Items.Clear(); // remove registro de erro e alerta...

    // O SELECT tras os registros com idpai=0 primeiro, assim serão incluídos os pais!
    //
    for (int i = 0; i < registros; i++) {
      string idpai = dt.Rows[i]["idpai"].ToString();
      string idmenu = dt.Rows[i]["idmenu"].ToString();
      string url = dt.Rows[i]["url"].ToString();
      string menu = dt.Rows[i]["menu"].ToString();
      string tooltip = dt.Rows[i]["tooltip"].ToString();
      string ativo = dt.Rows[i]["ativo"].ToString();
      string icone = dt.Rows[i]["icone"].ToString();

      MenuItem item = new MenuItem(menu, idmenu, icone, url);
      item.ToolTip = tooltip;
   
      int idPaiSelecionado = 0; // usado temporariamente para validar e atribuir o idPai do item selecionado!
      if (int.TryParse(idpai, out idPaiSelecionado)) {
      if (idPaiSelecionado.Equals(0)) {
        m.Items.Add(item);
      } else {
        foreach (MenuItem x in m.Items) {
        if (x.Value.Equals(idPaiSelecionado)) {
          m.Items[m.Items.IndexOf(x)].ChildItems.Add(item); // aqui eu adiciono o SUBMENU ao menu PAI correto. Mas não está funcionando direito
          break; // sai do FOR
        }
        }
      }
      }
Mas mesmo assim, tenho que fazer toda configuração visual via código, fica pesado. Pois ele não aproveita a que está já no MasterPage com CSS, entende?!
Mas... se alguém conseguir de um jeito diferente! Posta aqui! Valeu!



terra.jr
Turma 20.911

Mensagens : 1
Reputação : 1
Data de inscrição : 25/01/2012

Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 :: Programando :: C Sharp

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum