MDI - Windows Forms (C#)
1. Introdução
Como fazer para abrir Forms dentro de um *Form *principal em Windows Forms? Para isso é necessário entender o que é MDI e suas utilidades.
MDI significa* “Multiple Document Interface”, *o conceito dessa interface é abrir várias janelas dentro de uma janela principal, ou seja, adicionar diversas “janelas filhas” dentro de uma “janela pai”, exemplos dessa interface são os conhecidos Microsoft Word, Excel, etc..
Uma interface diferente sera o SDI, que significa “Single Document Interface”, nesse caso cada Form aberto representa uma janela diferente na aplicação, um exemplo seria o Internet Explorer.
Neste artigo, vamos criar um projeto em C# que engloba os principais conceitos da interface MDI.
2. Crie a Interface
Crie um novo projeto do tipo *Windows Forms *e chame de ProjetoMDI, adicione 4 novos *Forms *com os seguintes nomes: FormPrincipal, FormFilho1, FormFilho2 e FormFilho3.
Para o FormPrincipal, vá até a janela de propriedades e defina a propriedade*WindowState *como Maximized para que a janela abra em tela cheia.
Crie um MenuStrip no *FormPrincipal * e chame-o de *mnuPrincipal *e crie a seguinte estrutura de itens de menu (MenuItems):
http://www.thiagocoelho.net/blog/wp-content/uploads/2012/09/menu1.jpg
Estrutura do menu principal
3. Mão no Código!
Clique duas vezes no mnuAbrirFilho1 e adicione o seguinte código:
1 2 3 4 5 | private void mnuAbrirFilho1_Click( object sender, EventArgs e)
{
FormFilho1 form = new FormFilho1();
form.Show();
} |
Compile e execute a aplicação, clique no menu “Abrir Filho 1″ e repare que o FormFilho1 foi aberto em outra janela (interface SDI), veja que ao minimizar a janela aberta esta fica na barra do menu iniciar.
Como fazer para abrir dentro da janela principal? Serão dois passos simples. Primeiro precisamos dizer que o *FormPrincipal *é um MdiContainer, ou seja, ele pode ter Forms filhos dentro dele, para isso configure a propriedade *IsMdiContainer *como *true *no *FormPrincipal. *Feito isso, precisamos fazer uma alteração no nosso código onde abrimos o FormFilho1 dizendo quem será o “pai” dele, ou seja, dentro de qual janela ele abrirá, fazemos isso pela propriedade MdiParentde FormFilho1:
1 2 3 4 5 6 | private void mnuAbrirFilho1_Click( object sender, EventArgs e)
{
FormFilho1 form = new FormFilho1();
form.MdiParent = this ;
form.Show();
} |
Se você não sabe o que significa esse “this”, nada mais é que a instância do Form que você está trabalhando, dessa forma, falamos que o “pai” de FormFilho1 é o Form atual “this” que é o *FormPrincipal *(No VB.NET o “this” é o mesmo que “Me”).
Agora adicione os códigos para abrir os outros Forms:
1 2 3 4 5 6 7 8 9 10 11 12 13 | private void mnuAbrirFilho2_Click( object sender, EventArgs e)
{
FormFilho2 form = new FormFilho2();
form.MdiParent = this ;
form.Show();
}
private void mnuAbrirFilho3_Click( object sender, EventArgs e)
{
FormFilho3 form = new FormFilho3();
form.MdiParent = this ;
form.Show();
} |
Compile e execute a aplicação, abra varias vezes cada *Form *e veja que todos eles abrem dentro de FormPrincipal, minimize e maximize as janelas filhas abertas e veja que diferente da interface SDI, as janelas não aparecem na barra do menu iniciar, mas sim dentro de apenas uma janela, o FormPrincipal.
4. Forms Abertos
Imagine agora que você tem uma aplicação grande com a interface MDI e tem vários *Forms *abertos, uns minimizados e outros não e deseja ter um local no menu onde mostre todas as janelas abertas dentro da aplicação e que facilite a navegação entre elas? Você deve estar pensando que é algo muito complicado mas eu venho aqui desmentir seu pensamento e mostrar como é tão simples fazer isso.
Vá para a janela de propriedades de *mnuPrincipal *e altere a propriedade MdiWindowListItem para o nosso item de menu responsável por essa tarefa que no nosso caso é *mnuFormsAbertos. *Pronto! Ahhh, você tá mentindo né? Não estou, compile e execute sua aplicação, abra os Forms e veja como “magicamente” os *Forms *abertos foram parar lá no menu “Forms Abertos”:
http://www.thiagocoelho.net/blog/wp-content/uploads/2012/09/mdi21.jpg
Menu “Forms Abertos”
5. Layout dos Forms Filhos
E se agora você quiser organizar as janelas abertas em cascata, lado a lado horizontal ou vertical ou até arranjar os Forms que estão minimizados.
Para isso, clique duas vezes em cada item do menu *mnuJanela e *adicione os seguintes códigos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | private void mnuCascata_Click( object sender, EventArgs e)
{
this .LayoutMdi(MdiLayout.Cascade);
}
private void mnuHorizontal_Click( object sender, EventArgs e)
{
this .LayoutMdi(MdiLayout.TileHorizontal);
}
private void mnuVertical_Click( object sender, EventArgs e)
{
this .LayoutMdi(MdiLayout.TileVertical);
}
private void mnuIconesMinimizados_Click( object sender, EventArgs e)
{
this .LayoutMdi(MdiLayout.ArrangeIcons);
} |
Explicando o código acima, a função LayoutMdi é responsável por organizar o layout dos *Forms *filhos de FormPrincipal, aceita como parâmetro a Enum *MdiLayout *que contém 4 modos diferentes:
-* Cascade*: Os *Forms *são arranjados em cascata
-* TileHorizontal*: Os *Forms *são arranjados lado a lado horizontalmente
-* TileVertical*: Os *Forms *são arranjados lado a lado verticalmente
-* ArranjeIcons*: Os *Forms *estão minimizados são arranjados abaixo e a esquerda do FormPrincipal.
Compile e execute a aplicação, abra os 3 forms filhos e após clique no menu cascata, lado a lado horizontal e lado a lado vertical e veja as mudanças:
http://www.thiagocoelho.net/blog/wp-content/uploads/2012/09/mdi3.jpg
Lado a lado horizontalmente
http://www.thiagocoelho.net/blog/wp-content/uploads/2012/09/mdi4.jpg
Lado a lado verticalmente
Agora minimize os 3 forms filhos, clique e arraste as janelas minimizadas para algum local da janela principal e depois clique no menu “Ícones Minimizados”, veja o resultado:
http://www.thiagocoelho.net/blog/wp-content/uploads/2012/09/mdi5.jpg
Ícones minimizados
6. Algo mais com MDI
Você ainda pode obter uma coleção de todos os forms filhos que estão dentro do *FormPrincipal *através da coleção *this.MdiChildren, *veja o código a seguir que altera a propriedade *Text *de todos os forms filhos de FormPrincipal para “Novo Texto” contido em um evento de um botão chamado btnMdiChildren:
1 2 3 4 5 6 7 | private void btnMdiChildren_Click( object sender, EventArgs e)
{
foreach (Form form in this .MdiChildren)
{
form.Text = "Novo Texto" ;
}
} |
Também podemos utilizar a propriedade this.ActiveMdiChild para obter a instância do *Form *ativo na aplicação, o código a seguir, escreve “Novo Texto 2″ apenas no Form ativo, evento criado apra o botão btnActiveMdiChild:
1 2 3 4 | private void btnActiveMdiChild_Click( object sender, EventArgs e)
{
this .ActiveMdiChild.Text = "Novo Texto 2" ;
} |
Sabendo então que podemos pegar a instância de qualquer Form aberto no FormPrincipal, temos um leque de operações para serem feitas entre as janelas, eu ensino como fazer comunicação entre *Forms *de 3 formas diferentes neste post.
Espero ter ajudado à todos, abraços e até logo!