FOREACH COM ERRO NO MENUSTRIP

F001E 14/04/2014 15:50:03
#437267
Boa tarde a Todos...hoje estou meio Burrão....
Tenho esse código onde pego todos os itens do menustrip mas existem alguns separadores ToolStripSeparator no meio e no 3º ForEach da um erro que não pode converter ToolStripSeparador em ToolStripMenuItem e não estou conseguindo resolver isso...Alguém sabe como resolver ?

frmPrincipal F = new frmPrincipal();
foreach (Control Controle in F.Controls)
{
if (Controle is MenuStrip)
{
foreach (ToolStripMenuItem Menu in (Controle as MenuStrip).Items)
{
VerificaMenu(Menu.Text.Trim());
foreach (ToolStripMenuItem SubItemMenu in Menu.DropDownItems)
{
VerificaMenu(SubItemMenu.Text.Trim());
foreach (ToolStripMenuItem SubItemMenu1 in SubItemMenu.DropDownItems)
{
VerificaMenu(SubItemMenu1.Text.Trim());
}
}
}
}
}
KERPLUNK 14/04/2014 15:56:04
#437268
Antes do segundo foreach, verifique se (Controle as MenuStrip).Itens é null.
F001E 14/04/2014 17:01:57
#437270
Não funcionou nao...

foreach (Control Controle in F.Controls)
{
if (Controle is MenuStrip)
{
if ((Controle as MenuStrip).Items != null)
{
foreach (ToolStripMenuItem Menu in (Controle as MenuStrip).Items)
{
VerificaMenu(Menu.Text.Trim());
foreach (ToolStripMenuItem SubItemMenu in Menu.DropDownItems)
{
VerificaMenu(SubItemMenu.Text.Trim());
foreach (ToolStripMenuItem SubItemMenu1 in SubItemMenu.DropDownItems)
{
VerificaMenu(SubItemMenu1.Text.Trim());
}
}
}
}
}
}
KERPLUNK 14/04/2014 17:08:04
#437271
O caminho é por aí. Depure o código e use a watch window para ver cada coisa que está fazendo foreach.
F001E 14/04/2014 17:46:22
#437272
O problema que o 3º foreach ja carrega os itens inclusive o separador...o menu é assim:

passa pelo Cadastro no 2º foreach

passa pelo Parametros no 3º foreach

vai para o 4º foreach para pegar Empresa, Usuários e Permissão, mas daí volta para o 3º foreache onde dá pau por causa do separador embaixo do Parametros...
OCELOT 14/04/2014 17:50:38
#437273
Resposta escolhida
Esse seu código está digamos que meio [Ô]feio[Ô], o que aconteceria se você adicionasse mais um nível de sub menus? Iria adicionar mais um foreach?

Você pode resolver isso usando uma função recursiva, e verificar se a propriedade Items do ToolStripMenuItem é nulo não vai adiantar nada, já que o separador é um objeto do tipo ToolStripSeparator e ele não herda do ToolStripMenuItem, então sempre vai ocorrer o erro neste seu caso, o que precisa para corrigir isso é verificar se o item da coleção é um ToolStripMenuItem, o que não pode ser feito com o foreach do jeito que você fez.

Eu resolveria os dois problemas da seguinte forma, em vez de fazer um foreach dentro de um foreach dentro de outro foreach e assim por diante para cada nível de menu eu criaria uma função recursiva, como menus geralmente não tem muitos níveis isso não causaria nenhum problema e eu não teria que me preocupar com essa função no futuro quando mudasse os menus, e para fazer isso em vez de começar o MenuStrip eu usaria direto a coleção de itens dela, que é do tipo ToolStripItemCollection, que é o mesmo tipo que a propriedade DropDownItems retorna.

E como usamos C# podemos ainda usar um recurso dele que facilita a nossa vida e geralmente é pouco usado, mas serve perfeitamente para essa ocasião, que é o yield return.

O código da função recursiva ficaria assim
public IEnumerable<ToolStripMenuItem> ListarToolStripMenuItems(ToolStripItemCollection itensMenu)
{
foreach (var item in itensMenu)
{
var menuItem = item as ToolStripMenuItem;
if (menuItem != null)
{
yield return menuItem;
if (menuItem.HasDropDownItems)
{
foreach (var subItem in ListarToolStripMenuItems(menuItem.DropDownItems))
{
yield return subItem;
}
}
}
}
}

Então para usar isso, digamos que no meu Form eu tenha um MenuStrip chamado menuStrip1, no load deste form eu colocaria
foreach(var item in ListarToolStripMenuItems(menuStrip1.Items))
{
//aqui vai a função que usa o menu, por exemplo, seguindo o seu código
VerificaMenu(item.Text.Trim());
}
F001E 14/04/2014 18:03:02
#437274
OCELOT...eu vi alguma coisa sobre isso mas acabei não vendo a fundo...

Agora deu certo....valews;....
Tópico encerrado , respostas não são mais permitidas