FOREACH COM ERRO NO MENUSTRIP
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());
}
}
}
}
}
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());
}
}
}
}
}
Antes do segundo foreach, verifique se (Controle as MenuStrip).Itens é null.
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());
}
}
}
}
}
}
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());
}
}
}
}
}
}
O caminho é por aÃ. Depure o código e use a watch window para ver cada coisa que está fazendo foreach.
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...
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...
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
Então para usar isso, digamos que no meu Form eu tenha um MenuStrip chamado menuStrip1, no load deste form eu colocaria
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());
}
OCELOT...eu vi alguma coisa sobre isso mas acabei não vendo a fundo...
Agora deu certo....valews;....
Agora deu certo....valews;....
Tópico encerrado , respostas não são mais permitidas